Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphism, overloads and generics in C#

class Poly
    {
    public static void WriteVal(int i) { System.Console.Write("{0}\n", i); }
    public static void WriteVal(string s) { System.Console.Write("{0}\n", s); }
    }

class GenWriter<T>
    {
        public static void Write(T x) { Poly.WriteVal(x); }
    }

Why the innocent (for C++ programmer) method Write is not acceptable in C#?

You can see that the compiler tries to match the parameter type T to concrete overloads before instantiation:

Error 3 The best overloaded method match for 'TestGenericPolyMorph.Poly.WriteVal(int)' has some invalid arguments

Of course. the purpose was not to use the static method as above, the intention is to create a wrapper with polymorphic behavior. Note: I use VS 2010.

Please, note that all the needed information is available in compile time. Once again: the problem is that the validation is performed before the template instantiation.

Addition after the discussion:

Well, may be I have not stressed this out properly. The question was not only about the difference between generics and templates, but also about solution of the following problem: given set of overloads addressing different types, I want to generate set of wrapper classes providing virtual method (polymorphism) for these types. The price of resolution of virtual methods in run-time is minimal and does not hit performance. This is where C++ templates were handy. Obviously, the overhead of the run-time type resolution for dynamic is quite different. So, the question is whether one can convert existing overloads to polymorphism without replication of the code and without paying the performance penalty (e.g., I am not sure what I gain with dynamic compared to "switch" attempting to cast except of nicer syntax).

One of the solutions I have seen so far was to generate/emit code (sic!), i.e. instead of cut-and-paste to do this automatically.

So, instead of the C++ template processing we simply do it manually or just re-invent macro/template processor.

Anything better?

like image 431
Yuri S. Avatar asked Dec 14 '11 17:12

Yuri S.


People also ask

What is the polymorphism and generic?

Using Java Generic concept, we might write a generic method for sorting an array of objects, then invoke the generic method with Integer arrays, Double arrays, String arrays and so on, to sort the array elements. Polymorphism is the ability of an object to take on many forms.

What are the polymorphism and overloading?

Polymorphism means more than one form, same object performing different operations according to the requirement. Method overloading means writing two or more methods in the same class by using same method name, but the passing parameters is different.

What is polymorphism explain with example?

The word “polymorphism” means having many forms. In simple words, we can define polymorphism as the ability of a message to be displayed in more than one form. A real-life example of polymorphism is a person who at the same time can have different characteristics.


2 Answers

Short answer:

C# generics are not C++ templates; despite their similar syntax they are quite different. Templates are built at compile time, once per instantiation, and the templatized code must be correct for only the template arguments actually provided. Templates do tasks like overload resolution and type analysis once per instantiation; they are basically a smart "search and replace" mechanism on source code text.

C# generics are truly generic types; they must be correct for any possible type argument. The generic code is analyzed once, overload resolution is done once, and so on.

Long answer: This is a duplicate of

What are the differences between Generics in C# and Java... and Templates in C++?

See the long answers there for details.

See also my article on the subject:

http://blogs.msdn.com/b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx

like image 132
Eric Lippert Avatar answered Oct 10 '22 17:10

Eric Lippert


Why can't you simply write:

public static void Write<T>(T x) { System.Console.Write("{0}\n", x); }
like image 33
Tudor Avatar answered Oct 10 '22 18:10

Tudor