开发者

Problem in using C# generics with method overloading

开发者 https://www.devze.com 2023-01-31 11:15 出处:网络
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 an

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;
  }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号