针对通用接口创建扩展方法还是作为通用约束?

mic*_*ael 0 c# generics extension-methods interface generic-constraints

我不确定这两个签名是否有任何真正的区别:

public static class MyCustomExtensions
{
    public static bool IsFoo(this IComparable<T> value, T other)
        where T : IComparable<T>
    {
        // ...
    }

    public static bool IsFoo(this T value, T other)
        where T : IComparable<T>
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为这些操作几乎完全相同,但我不太确定......我在这里俯瞰什么?

ang*_*son 5

就在这里.

第一个签名将匹配任何可以与之比较的类型T,而不仅仅是T值.因此,任何实现的类型IComparable<int>都可以由第一个签名使用,而不仅仅是int.

例:

void Main()
{
    10.IsFoo(20).Dump();
    new Dummy().IsFoo(20).Dump();

    IComparable<int> x = 10;
    x.IsFoo(20).Dump();

    IComparable<int> y = new Dummy();
    y.IsFoo(20).Dump();
}

public class Dummy : IComparable<int>
{
    public int CompareTo(int other)
    {
        return 0;
    }
}

public static class Extensions
{
    public static bool IsFoo<T>(this IComparable<T> value, T other)
        where T : IComparable<T>
    {
        Debug.WriteLine("1");
        return false;
    }

    public static bool IsFoo<T>(this T value, T other)
        where T : IComparable<T>
    {
        Debug.WriteLine("2");
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

将输出:

2
False
1
False
1
False
1
False
Run Code Online (Sandbox Code Playgroud)

我用LINQPad测试了这个.