2010-07-15 87 views
3

Phil Haack's attempt on null or empty coalescing的启发,我试图为string对象以及IEnumerable<T>接口编写几个扩展方法来简化无效或无效的ckecking。然而,我遇到了一些问题:当我试图调用AsNullIsEmpty的版本时,编译器将我的字符串视为IEnumerable<char>,当然会给出错误的返回类型。对C#泛型的反约束

有没有什么办法对的IEnumerable版本的定义把“反限制”,这样我可以告诉编译器使用一个每当T类型是string?像

public static IEnumerable<T> AsNullIfEmpty(this IEnumerable<T> items) 
    where T !: string 

东西,我知道我可以只改变其中一人的名字,但我想有一致性相同的名称。

更新:原来我的问题与扩展方法解决了另一种方式,通过固定的简单和愚蠢的错误(我用的是str.IsNullOrEmpty(),在IEnumerable<T>扩展方法,而不是string.IsNullOrEmpty(str) ...),但由于对泛型的反约束问题仍然是一个有趣的问题,我不会删除它。

+0

编译器将采取最具体的可用方法。如果你实现了一个字符串,并确保它可以在Call站点使用,那么就不会有像描述的那样的问题 – 2010-07-15 12:28:38

回答

8

要做到这一点的唯一方法是创建此扩展的重载,接受string作为其this参数。

public static string AsNullIfEmpty(this string value) 

这样做会导致特定类型的版本被认为是比通用版本更好的过载匹配。

至于你的具体问题(“我能指定一个泛型类型参数的'反约束'吗?”),答案是否定的。尽管如此,您可以非常接近Obsolete属性。

[Obsolete("AsNullIfEmpty is not supported for strings.", true)] 
public static string AsNullIfEmpty(this string value) 

这将导致编译器报告此超载的错误。

+0

这就是我的 - 正如你在我的更新中看到的,扩展方法问题已经解决。 (由于另一个错误而存在问题...)。但是,有什么方法可以指定反约束? – 2010-07-15 12:28:30

+0

然后,当T是字符串时,您会得到具有相同签名的2种方法的良好智能感知。 – 2010-07-15 12:29:05

+0

@Tomas:对此有一个简单的答案:不,没有办法指定反约束。 – LukeH 2010-07-15 12:31:45