泛型方法的类型参数的类型推断

本文关键字:类型参数 泛型方法 类型 | 更新日期: 2023-09-27 18:21:55

我是Stack Overflow的新手,所以请放心!我正在深入阅读C#,但我遇到了一个我认为没有涵盖的场景。在网上快速搜索也没有得到任何结果。

假设我定义了以下重载方法:

void AreEqual<T>(T expected, T actual)
void AreEqual(object expected, object actual)

如果我调用AreEqual()而没有指定类型参数:

AreEqual("Hello", "Hello")

调用方法的通用版本还是非通用版本?泛型方法是使用推断的类型参数调用的,还是使用隐式转换为System.Object的方法参数调用的非泛型方法?

我希望我的问题很清楚。提前谢谢你的建议。

泛型方法的类型参数的类型推断

泛型可以生成函数AreEqual(string, string)。这比AreEqual(object, object)更匹配,因此选择了泛型函数。

有趣的是,编译器会选择这个泛型函数,即使它会导致违反约束的错误。

看看这个例子:

using System.Diagnostics;
namespace ConsoleSandbox
{
    interface IBar
    {
    }
    class Program
    {
        static void Foo<T>(T obj1) where T: IBar
        {
            Trace.WriteLine("Inside Foo<T>");
        }

        static void Foo(object obj)
        {
            Trace.WriteLine("Inside Foo Object");
        }
        static void Main(string[] args)
        {
            Foo("Hello");
        }
    }
}

即使在这里,它也会选择通用版本而不是非通用版本。然后你会得到这个错误:

类型"string"不能用作泛型中的类型参数"T"类型或方法"ConsoleSandbox.Program.Foo(T)"。没有从"string"到"ConsoleSandbox.IBar'."的隐式引用转换

但是,如果添加一个函数Foo(string obj1),它就会起作用。