我试图根据泛型类型调用重载方法。我一直用C ++做这件事,没有任何痛苦。但我真的不明白为什么我不能在C#中使用泛型来做这件事。任何人都可以帮助我如何在C#中使用泛型来实现这一目标?
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);
}
}
答案 0 :(得分:4)
这不起作用,因为C#泛型与C ++模板根本不同。 .NET泛型类实例化是在运行时创建的,而C ++模板实例化是在编译时创建的(据我所知;我的C ++非常生疏)。通用Do<T>
方法必须在编译时知道 一个要调用的方法,可以将其烘焙到生成的IL中。
实现此目的的方法是使用反射,或dynamic
(C#4中的新增内容):
class Test<T>
{
public T Val;
public void Do(T val)
{
Val = val;
dynamic dynVal = Val;
MainClass.Print(dynVal);
}
}
使用dynamic
,方法查找将在运行时进行。请注意,这与泛型完全分开,并且在非泛型代码中也同样有效。
答案 1 :(得分:1)
我可能会遗漏一些东西,但在你的代码中你有:
public void Do(T val)
{
Val = val;
MainClass.Print(Val);
}
and in you main method you have:
test.Do(); //no parameter provided.
答案 2 :(得分:1)
您遇到的问题是C#没有根据您的类型T选择合适的方法。您必须制定一个这样的解决方法:
void Print<T>(T val)
{
switch(val.GetType())
{
case typeof(UInt64):
Console.WriteLine(...); break;
}
}