C# virtual static method

前端 未结 9 1274
盖世英雄少女心
盖世英雄少女心 2020-12-14 01:27

Why is static virtual impossible? Is C# dependent or just don\'t have any sense in the OO world?

I know the concept has already been underlined but I did not find a

相关标签:
9条回答
  • 2020-12-14 02:07

    Yes it is possible.

    The most wanted use case for that is to have factories which can be "overriden"

    In order to do this, you will have to rely on generic type parameters using the F-bounded polymorphism.

    Example 1 Let's take a factory example:

    class A: { public static A Create(int number) { return ... ;} }
    class B: A { /* How to override the static Create method to return B? */}
    

    You also want createB to be accessible and returning B objects in the B class. Or you might like A's static functions to be a library that should be extensible by B. Solution:

    class A<T> where T: A<T> { public static T Create(int number) { return ...; } }
    class B: A<B>  { /* no create function */ }
    B theb = B.Create(2);       // Perfectly fine.
    A thea = A.Create(0);       // Here as well
    

    Example 2 (advanced): Let's define a static function to multiply matrices of values.

    public abstract class Value<T> where T : Value<T> {
      //This method is static but by subclassing T we can use virtual methods.
      public static Matrix<T> MultiplyMatrix(Matrix<T> m1, Matrix<T> m2) {
        return // Code to multiply two matrices using add and multiply;
      }
      public abstract T multiply(T other);
      public abstract T add(T other);
      public abstract T opposed();
      public T minus(T other) {
        return this.add(other.opposed());
      }
    }
    // Abstract override
    public abstract class Number<T> : Value<T> where T: Number<T> {
      protected double real;
    
      /// Note: The use of MultiplyMatrix returns a Matrix of Number here.
      public Matrix<T> timesVector(List<T> vector) {
        return MultiplyMatrix(new Matrix<T>() {this as T}, new Matrix<T>(vector));
      }
    }
    public class ComplexNumber : Number<ComplexNumber> {
      protected double imag;
      /// Note: The use of MultiplyMatrix returns a Matrix of ComplexNumber here.
    }
    

    Now you can also use the static MultiplyMatrix method to return a matrix of complex numbers directly from ComplexNumber

    Matrix<ComplexNumber> result = ComplexNumber.MultiplyMatrix(matrix1, matrix2);
    
    0 讨论(0)
  • 2020-12-14 02:07

    To summarize all the options presented:

    • This is not a part of C# because in it, static means "not bound to anything at runtime" as it has ever since C (and maybe earlier). static entities are bound to the declaring type (thus are able to access its other static entities), but only at compile time.

      • This is possible in other languages where a static equivalent (if needed at all) means "bound to a type object at runtime" instead. Examples include Delphi, Python, PHP.
    • This can be emulated in a number of ways which can be classified as:

      1. Use runtime binding
        • Static methods with a singleton object or lookalike
        • Virtual method that returns the same for all instances
          • Redefined in a derived type to return a different result (constant or derived from static members of the redefining type)
          • Retrieves the type object from the instance
      2. Use compile-time binding
        • Use a template that modifies the code for each derived type to access the same-named entities of that type, e.g. with the CRTP
    0 讨论(0)
  • 2020-12-14 02:08

    Eric Lippert has a blog post about this, and as usual with his posts, he covers the subject in great depth:

    http://blogs.msdn.com/b/ericlippert/archive/2007/06/14/calling-static-methods-on-type-parameters-is-illegal-part-one.aspx

    “virtual” and “static” are opposites! “virtual” means “determine the method to be called based on run time type information”, and “static” means “determine the method to be called solely based on compile time static analysis”

    0 讨论(0)
提交回复
热议问题