C# generic interface specialization

前端 未结 6 1737
自闭症患者
自闭症患者 2020-12-10 02:42

I wonder if it is in any way possible to specialize generic interface methods somehow in C#? I have found similar questions, but nothing exactly like this. Now I suspect tha

6条回答
  •  一整个雨季
    2020-12-10 03:18

    Overload resolution is performed at compile-time, not at run-time based on the actual type of the passed value.

    IStorage i = new Storage();
    i.Store("somestring"); // Prints Generic
    i.Store(1); // Prints Generic
    

    This will always call the "generic" method, because there is only one overload of Store in IStorage and the compiler doesn't know that i actually contains a Storage object. How can the compiler know about the other overload in Storage?

    Storage s = (Storage)i;
    s.Store("somestring"); // Prints Generic
    s.Store(1); // Prints Specific
    

    Here, the compiler knows that s contains a Storage object (or one deriving from Storage), because s is declared that way. So it sees two overloads. It chooses the specific overload for int values, because overload resolution rules say to prefer specific overloads over generic overloads.


    It's technically possible to determine typeof(T) in the generic method at run-time and forward the method call to a specific method. But if you think about it, this doesn't make a lot of sense. A generic method means that the same implementation works for arguments of different, unrelated types. If you want different implementations for different types, you shouldn't use generics for this.


    void Foo(T t)
    {
        SubFoo(t);
    }
    
    void SubFoo(T t);
    void SubFoo(int t);
    

    Generics work quite a bit different from C++ templates. The C# compiler compiles Foo only once -- to a generic method. Remember: generic means same implementation for different types. The C# compiler does not know at compile-time if T is going to be an int or a string or any other type. So the only possible implementation of Foo that works for any T is to call SubFoo. If one of the SubFoo overloads would be called depending on T, the implementation of Foo wouldn't be the same for all T any more.

提交回复
热议问题