关于两种不同类扩展模式的问题

时间:2011-07-22 13:45:21

标签: c# .net extension-methods

以下两种方法之间的语义差异是什么:

public static bool IsNullOrEmpty(this Array value)
{
    return (value == null || value.Length == 0);
}

public static bool IsNullOrEmpty<T>(this T[] value)
{
    return (value == null || value.Length == 0);
}

一个人有优势吗?

3 个答案:

答案 0 :(得分:4)

第一个适用于任何数组,包括矩形数组和下限为非零的数组。当数组的编译时类型只是Array时,它也会起作用,这可能偶尔会发生在类型相当弱的API上。

简而言之,第一种更为通用,应该适用于第二种情况。

(我假设你想从中获得任何“额外”功能,例如第二种形式的T的额外约束......你只是想要一些东西将确定数组引用是否为null或引用空数组。)

编辑:对于IEnumerable,您可以使用:

public static bool IsNullOrEmpty(this IEnumerable value)
{
    if (value == null)
    {
        return true;
    }
    var iterator = value.GetEnumerator();
    try
    {
        return !iterator.MoveNext();
    }
    finally
    {
        // Non-generic IEnumerator doesn't extend IDisposable
        IDisposable disposable = iterator as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }
}

缺点当然是它很容易产生副作用 - 例如,你可以传入一个LINQ查询,最终会与数据库交谈。

答案 1 :(得分:2)

通过去泛型你可以添加一个条件,进一步限制T可以...

所以你可以用“where T:class”或“where T:ISomeInterface”限制它(最值得注意的是你可以做“T:IDisposable”,并确保你的扩展不能使用任何无法处理的东西< / p>

答案 2 :(得分:1)

第二个使用泛型因此是类型安全的。