【问题标题】:C# Overload Resolution with type constraint not choosing method I would expect具有类型约束的 C# 重载解决方案没有选择我期望的方法
【发布时间】:2019-05-18 15:44:23
【问题描述】:

尽管类型约束为编译器提供了足够的信息来选择正确的重载方法签名,但执行的方法并不是我所期望的

没有泛型方法,它会像我预期的那样调用void DoSomething(IInterface obj)。使用通用方法,void DoSomething<T>(T obj) 会被调用,因为在这种情况下,出于某种原因,它被认为是更好的候选对象。


interface IInterface
{
    void Method();  
}

class A : IInterface
{
    public void Method()
    {

    }
}

public class Program
{
    static void Gen<T>(T obj) where T : IInterface
    {
        DoSomething(obj);
    }

    static void DoSomething<T>(T obj)
    {
        Console.WriteLine("IN GENERIC DO SOMETHING");   
    }

    static void DoSomething(IInterface obj)
    {
        Console.WriteLine("IN INTERFACE DOSOMETHING");
    }

    static void DoSomething(object obj)
    {
        Console.WriteLine("IN OBJ DO SOMRTHING");
    }
    public static void Main()
    {
        IInterface i = new A();
        Gen(i);
    }
}

我希望在所有情况下都调用非泛型 DoSomething 方法,因为由于约束,编译器具有可使用的具体类型。相反,正在调用通用的 DoSomething。只有当我删除泛型版本时才会选择非泛型方法。

【问题讨论】:

  • 正如代码所示,您正在调用 Gen 的唯一重载。
  • 不幸的是,这个问题看起来像是一个错字。我真的不是要对提出问题的人产生负面影响。但从某种意义上说,它在问为什么打电话给Gen 打电话给Gen。如果调用Gen没有调用Gen,那将是出乎意料的。

标签: c# generics overload-resolution


【解决方案1】:

调用泛型方法实际上是有道理的,因为它是所有三个方法中最具体的

接口和对象不太具体,因为它们都需要向上转换,而泛型则不需要。

此外:泛型方法的想法是它的行为独立于它专门化的实际类型。特别是,运行时只会生成一个涵盖所有引用类型案例的特化。

【讨论】:

  • 好吧,我错了,因为他将变量键入为IInterface,而不是A。解决方案很简单:只有一个Gen 方法!(还有很多DoSomethings)
  • 不是 3 个中最具体的一个 DoSomething 已经被特定的 IInterface 具体类型重载了吗?约束已经将 T 绑定为这个接口,所以出于所有意图和目的,它的类型不应该是这个接口,因此不需要强制转换吗?
  • 您看,Gen 方法的代码与类型 T 无关,在这种情况下泛型方法是最具体的。在 T is 接口类型的特殊情况下,我看到你从哪里来,那么接口类型的实际重载应该是更具体的情况。但没有这种特殊情况。在引用类型的情况下,泛型方法不会被进一步特化。
猜你喜欢
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
相关资源
最近更新 更多