Should I mark all methods virtual?

In Java, you can mark a method as final to make it impossible.

In C #, you must mark the method as virtual so that you can override it.

Does this mean that in C # you should mark all methods virtual (with the exception of a few that you do not want to override), since most likely you do not know how your class can be inherited?

+67
java methods c # virtual-method
Jan 22
source share
8 answers

In C #, you must mark the method as virtual so that you can override it. Does this mean that in C # you should mark all methods virtual (with the exception of a few that you do not want to override), since most likely you do not know how your class can be inherited?

No. If the developers of the language believed that virtual was supposed to be the default, then it would be the default .

Overridablility is a function, and, like all functions, it has its costs. The cost of the redefinable method is significant: there are high costs for design, implementation and testing, especially if there is any “sensitivity” to the class; virtual methods are ways of introducing unverified third-party code into the system and affecting security.

If you don’t know how you intend to inherit your class, do not publish your class because you have not finished developing it. Your extensibility model is definitely something you need to know in advance; this should deeply affect your design and testing strategy.

I advocate that all classes be sealed, and that all methods are not virtual, until you have a real goal associated with the click to open or make the method virtual.

Basically your question is: “I don't know how my clients intend to use my class, so should I make it arbitrarily extensible?” No; You must become recognizable! You didn’t ask: “I don’t know how my clients will use my class, so should I use all my properties to read and write? And should I use all my methods to read and write delegate type properties so that my users can replace any method with your own implementation? " No, do not do any of these things until you get evidence that the user really needs this feature! Spend your precious time on designing, testing and implementing functions that users really need and need, and do it from a knowledge perspective.

+133
Jan 22 '13 at 4:07
source share

In my opinion, the currently accepted answer is too dogmatic.

The fact is that when you do not mark a method as virtual , others cannot override its behavior, and when you mark a class as sealed , others cannot inherit from the class. This can cause significant pain. I don’t know how many times I have cursed the API for marking sealed classes or not marking virtual methods simply because they did not expect my use.

Theoretically, this may be the right approach, allowing you to only redefine methods and inherit classes that should be overridden and inherited, but in practice it is impossible to predict all possible scenarios, and there really is no good reason to be so closed in.

  • Unless you have a good reason, do not put classes as sealed .
  • If your library is intended to be consumed by others, try tagging the main methods of the class that contain virtual behavior.

One way to make a call is to look at the name of a method or property. The GetLength () method in List does exactly what the name implies, and this does not allow significant interpretation. Changing its implementation will probably not be very transparent, so you probably don't need to designate it as virtual . Marking the Add method as virtual is much more useful since someone can create a special List that accepts only certain objects using the Add method, etc. Another example is user controls. You would like to make the basic drawing method virtual so that others can use the bulk of the behavior and just change the look, but you probably won't override the X and Y properties.

In the end, you often do not need to make this decision right away. In an internal project where you can easily change the code, I would not worry about these things. If you need to override a method, you can always make it virtual when that happens. On the contrary, if the project is an API or a library that is consumed by others and is slowly being updated, then it is certainly worth considering which classes and methods can be useful. In this case, I believe that it is better to be open rather than strictly closed.

+23
Jan 29 '13 at 0:10
source share

No! Since you do not know how your class will be inherited, you should only mark the virtual method if you know that you want to override it.

+22
Jan 22 '13 at 3:56
source share

No. Only the methods that you want derived classes to specify must be virtual.

Virtual is not connected with the final.

To prevent overriding the virtual method in C #, you use sealed

 public class MyClass { public sealed override void MyFinalMethod() {...} } 
+5
Jan 22 '13 at 4:01
source share

We can cause reasons for / again in the camp, but this is completely useless.

There are millions of unintended incomplete public methods in Java, but we hear very few horrible stories.

There are millions of closed public methods in C #, and we hear very few horrible stories.

So, this is not very important - the need to redefine a public method is rare, so it discusses in any case.




This reminds me of another argument - whether the local variable should be final by default. This is a pretty good idea, but we cannot exaggerate how valuable it is. There are billions of local variables that may be, but not final, but this has been shown to be a real problem.

+4
Jan 22 '13 at 16:56
source share

Creating a virtual method usually slows down any code that should call it. This slowdown will be negligible, but in some cases it can be quite large (among other things, because non-virtual method calls can be aligned, which, in turn, allows the optimizer to eliminate unnecessary operations). It is not always possible to predict the extent to which virtual calls can affect execution speed, and you usually need to do something that will make the code slower, unless there is a noticeable advantage to this.

The performance advantage when creating non-virtual methods in many cases is probably enough to justify that the default methods are not virtual, but when classes are intended to be inherited, most methods should be virtual and unsealed; the main use for non-virtual or private methods should be like a wrapper for other (possibly protected) virtual methods (code that wants to change the basic behavior must override the corresponding virtual, not the wrapper).

Often, there are reasons for not observing classes for marking as sealed or limiting inheritance for other classes in the assembly. Among other things, if a class is externally inherited, all members with a protected scope are effectively added to their public API, and any changes in their behavior in the base class can violate any derived classes that rely on this behavior. On the other hand, if a class is inherited, then its virtual methods do not actually increase its impact. In any case, this can reduce the dependence of the derived class on the internal components of the base class, allowing them to completely “bury” aspects of the implementation of the base class that are no longer related to the derived class [for example, if the List<T> members were virtual, the derived class, which overloaded them, could use an array of arrays to store things (avoiding problems with large object heaps), and would not have to try to save the private array used by List<T> according to the array of arrays.

+1
Jun 05 '13 at 19:19
source share

No, you should not mark all methods as virtual. You should consider how your class can be inherited. If the class should not be inherited, then mark it sealed and, obviously, the members should not be virtual. If your class is likely to inherit, you really should maximize your ability to override behavior. Therefore, generously use virtual everywhere in such classes if you have no reason.

0
Nov 15 '18 at 20:55
source share

I cannot comment (not impressed with the reputation system here), but I would like to add Klug to the answer:

Sometimes someone down the line wants to change how Length () works.

The fact is that I'm trying to modify the game that the designer tried to make as possible. However, they still did not mark everything as “virtual,” so ... I cannot redefine a very similar “account”.

I suppose most of the people answering here will say that the original author should not have used C # at all if they intended to allow modding?

So. Think about how useful it is for your code to be different, and then make a decision.

-one
Dec 05 '18 at 17:07
source share



All Articles