C#:泛型方法没有';t调用特定的方法重载

本文关键字:调用 重载 方法 泛型方法 | 更新日期: 2023-09-27 18:20:57

我正试图在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();
    }
}

C#:泛型方法没有';t调用特定的方法重载

有什么方法可以纠正这种行为吗?

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

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

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

现在,它将在执行时基于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);
    }
}

这显然很可怕。