C#:通用方法不调用特定方法重载

Tom*_*ank 9 c# generics polymorphism mono unity-game-engine

我正在尝试在C#中创建一个泛型方法,它将根据其主体中的参数数据类型调用不同的方法,然后处理它们的结果.我试图通过创建一个通用的包装器方法来实现这一点,然后提供处理方法的几个重载 - 包括一个通用的,如果没有特定的重载可用.

当我直接调用处理方法时,正确选择了适当的版本.但是当我从包装器方法调用它时,它总是选择泛型方法,即使我传递给它的特定数据类型存在匹配的重载.

有没有办法调整代码使其行为符合我的需要?或者我必须使用不同的方法.

我需要代码与Mono 2.6兼容.

using System;

class Program
{
    static void Func<T>(T val)
    {
        Console.WriteLine("Generic Func");
    }

    static void Func(int val)
    {
        Console.WriteLine("Int Func");
    }

    static void Func(string val)
    {
        Console.WriteLine("String Func");
    }

    static void FuncWrap<T>(T val)
    {
        Console.Write("Wrap: ");
        Func(val);
    }

    static void Main(string[] args)
    {
        Func(2);
        Func("Potato");
        Func(2.0);

        FuncWrap(2);
        FuncWrap("Potato");
        FuncWrap(2.0);

        Console.Read();
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 14

有没有办法纠正这种行为?

根据C#语言规范,它已经是正确的行为.Func被调用内部的重载FuncWrap通常在编译时确定,因此它不能Func根据执行时类型选择不同的重载.

但是,改变行为的一种方法是使用动态类型:

static void FuncWrap<T>(T val)
{
    Console.Write("Wrap: ");
    dynamic x = val;
    Func(x);
}
Run Code Online (Sandbox Code Playgroud)

现在,它将根据值的实际类型在执行时执行重载解析x.这会产生性能成本,但应该按照您的要求进行.

或者,您可以硬编码重载的知识:

static void FuncWrap<T>(T val)
{
    Console.Write("Wrap: ");
    if (typeof(T) == typeof(string))
    {
        Func((string)(object)val);
    }
    else if (typeof(T) == typeof(int))
    {
        Func((int)(object)val);
    }
    else
    {
        Func(val);
    }
}
Run Code Online (Sandbox Code Playgroud)

但这显然非常可怕.