通过泛型访问扩展方法总是匹配最不具体的选项?

Sco*_*ler 4 c# generics extension-methods

  • 有一组我不拥有的课程 - 我无法改变它们.
  • 我想为每个类添加一个识别参数,使用每个类中有一个的现有字段.
  • 因此,我创建了一组扩展方法来从每个类中获取此字段,对于没有特定实现的任何类,都使用默认方法.

这在直接访问新的扩展方法(下面的示例中的前三个写入)时工作正常,但是当实例首次传递到泛型方法时,所选的扩展方法始终是对象的一个​​(后三个写入) ).

我做错了什么,或者这是C#编译器的限制?

public class Call { public string Number { get; set; } }
public class Message { public string Address { get; set; } }
public class Unknown { }

public static class Extensions
{
    public static string ID(this object item) { return "Unknown"; }
    public static string ID(this Call item) { return item.Number; }
    public static string ID(this Message item) { return item.Address; }
}

internal class Program
{
    private static void Main()
    {
        var call = new Call { Number = "555-1212" };
        var msg = new Message { Address = "you@email.com" };
        var other = new Unknown();

        // These work just as I would expect
        // - printing out Number, Address, or the default
        System.Console.WriteLine("Call = {0}", call.ID());
        System.Console.WriteLine("Message = {0}", msg.ID());
        System.Console.WriteLine("Unknown = {0}", other.ID());
        System.Console.WriteLine();

        // These all print out "Unknown"
        System.Console.WriteLine("Call = {0}", GetID(call));
        System.Console.WriteLine("Message = {0}", GetID(msg));
        System.Console.WriteLine("Unknown = {0}", GetID(other));
    }

    public static string GetID<T>(T item)
    {
        return item.ID();
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

过载分辨率在编译时执行.编译器一无所知T,所以唯一适用的重载是这个:

public static string ID(this object item) { return "Unknown"; }
Run Code Online (Sandbox Code Playgroud)

如果您想在执行时有效地执行重载解析,并且如果您正在使用C#4,则可能需要考虑使用dynamic- 遗憾的是,它不直接支持扩展方法:

public static string GetID(dynamic item)
{
    return Extensions.ID(item);
}
Run Code Online (Sandbox Code Playgroud)