Problem in using C# generics with method overloading
I am trying to call an overloaded method based on the generic type. I've been doing this in C++ without any pain. But I really don't understand why am not able to do this in C# with generics. Can anybody help me how can I achieve this in C# with generics?
class Test<T>
{
public T Val;
public void Do(T val)
{
Val = val;
MainClass.Print(Val);
}
}
class MainClass
{
public static void Print(UInt16 val)
{
Console.WriteLine("UInt16: " + val.ToString());
}
public static void Print(UInt32 val)
{
Console.WriteLine("UInt32: " + val.ToString());
}
public static void Print(UInt64 val)
{
Console.WriteLine("UInt64: " + val.ToString());
}
public static void Main (string[] args)
{
Test<UInt16> test = new Test<UInt16>();
test.Do(0);
}
}开发者_如何学编程
This won't work because C# generics are fundamentally different to C++ templates. .NET generic class instantiations are created at run-time, whereas C++ template instantiations are created at compile-time (as far as I know; my C++ is very rusty). The generic Do<T>
method has to know at compile time a single method to call that can be baked into the resulting IL.
The way to accomplish this is to use reflection, or dynamic
(new in C#4):
class Test<T>
{
public T Val;
public void Do(T val)
{
Val = val;
dynamic dynVal = Val;
MainClass.Print(dynVal);
}
}
With dynamic
, the method lookup will be at runtime. Note that this is completely separate to generics, and will work equally well in non-generic code.
I might be missing something, but in your code you have:
public void Do(T val)
{
Val = val;
MainClass.Print(Val);
}
and in you main method you have:
test.Do(); //no parameter provided.
The problem youre encountering is that C# desn't select the appropriate method based on your type T. You'll have to make a workaound like this:
void Print<T>(T val)
{
switch(val.GetType())
{
case typeof(UInt64):
Console.WriteLine(...); break;
}
}
精彩评论