I've been working with providers a fair bit lately, and I came across an interesting situation where I wanted to have an abstract class that had an abstract static method. I read a few posts on the topic, and it sort of made sense, but is there a nice clear explanation?
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Generic Generics in Managed C++
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
Static methods are not instantiated as such, they're just available without an object reference.
A call to a static method is done through the class name, not through an object reference, and the IL code to call it will call the abstract method through the name of the class that defined it, not necessarily the name of the class you used.
Let me show an example.
With the following code:
If you call B.Test, like this:
Then the actual code inside the Main method is as follows:
As you can see, the call is made to A.Test, because it was the A class that defined it, and not to B.Test, even though you can write the code that way.
If you had class types, like in Delphi, where you can make a variable referring to a type and not an object, you would have more use for virtual and thus abstract static methods (and also constructors), but they aren't available and thus static calls are non-virtual in .NET.
I realize that the IL designers could allow the code to be compiled to call B.Test, and resolve the call at runtime, but it still wouldn't be virtual, as you would still have to write some kind of class name there.
Virtual methods, and thus abstract ones, are only useful when you're using a variable which, at runtime, can contain many different types of objects, and you thus want to call the right method for the current object you have in the variable. With static methods you need to go through a class name anyway, so the exact method to call is known at compile time because it can't and won't change.
Thus, virtual/abstract static methods are not available in .NET.
We actually override static methods (in delphi), it's a bit ugly, but it works just fine for our needs.
We use it so the classes can have a list of their available objects without the class instance, for example, we have a method that looks like this:
It's ugly but necessary, this way we can instantiate just what is needed, instead of having all the classes instantianted just to search for the available objects.
This was a simple example, but the application itself is a client-server application which has all the classes available in just one server, and multiple different clients which might not need everything the server has and will never need an object instance.
So this is much easier to maintain than having one different server application for each client.
Hope the example was clear.
Another respondent (McDowell) said that polymorphism only works for object instances. That should be qualified; there are languages that do treat classes as instances of a "Class" or "Metaclass" type. These languages do support polymorphism for both instance and class (static) methods.
C#, like Java and C++ before it, is not such a language; the
static
keyword is used explicitly to denote that the method is statically-bound rather than dynamic/virtual.The abstract methods are implicitly virtual. Abstract methods require an instance, but static methods do not have an instance. So, you can have a static method in an abstract class, it just cannot be static abstract (or abstract static).
Here is a situation where there is definitely a need for inheritance for static fields and methods:
Static methods cannot be inherited or overridden, and that is why they can't be abstract. Since static methods are defined on the type, not the instance, of a class, they must be called explicitly on that type. So when you want to call a method on a child class, you need to use its name to call it. This makes inheritance irrelevant.
Assume you could, for a moment, inherit static methods. Imagine this scenario:
If you call Base.GetNumber(), which method would be called? Which value returned? Its pretty easy to see that without creating instances of objects, inheritance is rather hard. Abstract methods without inheritance are just methods that don't have a body, so can't be called.