6

By that I mean, it is possible to mark a virtual method in C# as final so no other types deriving from this type, can override it ever again?

Joan Venge
  • 315,713
  • 212
  • 479
  • 689
  • Out of curiosity, what is your usage case? This is a fairly rarely used feature. What's the scenario you've got where it makes sense to seal the *method* but not the *class*? – Eric Lippert Jan 12 '11 at 22:00
  • @Eric: Actually I don't have any use case :O But what happened is this. I am using a 3rd party .NET library that's not out yet. This library has a lot of types where they only have internal constructors. I want to make my own types deriving from these, but the way it's, it's not possible because the constructors have to be public. I asked them for it, and they said virtual methods can cause hard to debug, tricky bugs, so they can't do this. I vaguely remembered a way to "finalize"/seal virtual methods so that's why I asked this, and told this to them, that if they are concerned, they can use.. – Joan Venge Jan 12 '11 at 22:50
  • the sealed keyword to seal those virtual methods. Also told them if inheritance isn't intended for their library, then the types should be sealed for performance. But with these types having internal constructors, it's not possible to really make use of them. What do you think? Do you think their concerns against inheritance and virtual methods are valid? – Joan Venge Jan 12 '11 at 22:52
  • 1
    My opinion is that *extensibility is a feature*, and features have to be designed, specified, implemented, tested, documented, shipped and maintained. All of those things add cost. You can either have an extensible type that was not carefully designed that might not meet real customer needs, or you can spend the money to make it properly extensible, or you can make it non-extensible. In a world of limited budgets I am personally inclined to go for the third option. – Eric Lippert Jan 13 '11 at 00:36
  • 2
    It is possible that the reason they have a non-sealed class with inaccessible constructors is because they want to do inheritance internally, which is lower design, testing, documentation and maintenance burden than making inheritance available to the public. If they are not doing that then I agree that it is better to also seal the class, to make it dead obvious that the intention is to make a non-inheritable class. – Eric Lippert Jan 13 '11 at 00:38
  • @Eric: Thanks Eric, value your opinion. That's why I as someone who could use their library in a production provided them a very valid real world case to consider. I didn't ask for it just because but it would actually really make things easier. My opinion is that they didn't realize this would be needed so now are halfway between. I wish companies listen to customers more, like you try to get valid opinions. – Joan Venge Jan 13 '11 at 02:13
  • The situation that brought me to this question is one where the base classes of a framework need to be able to have virtual methods to allow alteration of critical functionality within the framework, however it is not desired that some (but not all) of that functionality be able to be changed by users of the framework. Essentially, it is very useful as a mechanism to protect critical code paths while leaving non-critical paths open to being changed. – AJ Henderson Oct 10 '12 at 20:34

2 Answers2

23

Yes: when overriding a method you can also declare it sealed.

Jeff Sternal
  • 47,787
  • 8
  • 93
  • 120
  • 2
    Good answer. One point of clarification to the OP; only the overrides of virtual methods (which are themselves also virtual) can be sealed; the declaration that has `virtual` cannot also be `sealed`. It's redundant; the sealed keyword "undoes" a virtual or abstract keyword which made the method virtual in the base class. There must be at least one level of inheritance between making the method virtual and sealing it. – KeithS Jan 12 '11 at 21:10
  • Thanks KeithS, can you please give a code example to this? I don't think I understood it. – Joan Venge Jan 12 '11 at 21:16
  • 3
    basically, `public override sealed void MyMethod()` compiles. `public virtual sealed void MyMethod()` does not, because at the same level of inheritance, you are marking the method as overridable and not overridable. It's redundant; `public void MyMethod()` would create a non-overridable method. That was the point I was trying to make; though virtual methods can be sealed, they must actually be overrides of the base method that was originally marked virtual. – KeithS Jan 12 '11 at 21:22
  • Thanks, but can you seal a virtual method at any level? Like say, a method in base is virtual, can MyType:base seal this method in MyType? – Joan Venge Jan 12 '11 at 21:24
  • 1
    Any level except the highest level at which this method exists as a virtual member. So there's a class A with MyMethod marked virtual, then B:A and C:B. Either B or C can seal the method, but A cannot. – KeithS Jan 12 '11 at 21:26
7

You can use sealed.

Aaron McIver
  • 24,527
  • 5
  • 59
  • 88