使用C#泛型和方法重载的问题

时间:2010-12-21 17:49:05

标签: c# generics

我试图根据泛型类型调用重载方法。我一直用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);

    }
}

3 个答案:

答案 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;
  }
}