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

Posted

技术标签:

【中文标题】泛型方法的类型参数的类型推断【英文标题】:Type inference for type arguments of generic methods 【发布时间】:2012-02-20 23:18:18 【问题描述】:

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

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

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

void AreEqual(object expected, object actual)

如果我在没有指定类型参数的情况下调用AreEqual()

AreEqual("Hello", "Hello")

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

我希望我的问题很清楚。提前感谢您的任何建议。

【问题讨论】:

你当然可以写一些简单的代码来检查这个...... blogs.msdn.com/b/ericlippert/archive/2009/07/30/… @Mitch Wheat - 是的,但那样我就不必发表我的第一篇文章了。其他人在这里看到答案很有用。 @Michael Edenfield - 很好,我听说过关于 Eric Lippert 博客的好消息。 【参考方案1】:

泛型可以生成函数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)它就会起作用。

【讨论】:

很好的答案,谢谢!很好的例子,我自己试过只是为了确认:-) 请注意,重载解析是由 C# 编译器完成的,而不是 .NET 框架。

以上是关于泛型方法的类型参数的类型推断的主要内容,如果未能解决你的问题,请参考以下文章

在 TypeScript 中,如何在具有多个类型参数的方法中推断出泛型类型参数?

C# 泛型方法类型参数不是从用法中推断出来的

请教关于java的泛型方法

请教关于java的泛型方法

打字稿泛型:从函数参数的类型推断类型?

013.泛型窗体常用属性