C#泛型的反约束

C#泛型的反约束,c#,generics,constraints,C#,Generics,Constraints,受此启发,我正在尝试为字符串对象以及IEnumerable接口编写两个扩展方法,以简化null或emtpy检查。但是,我遇到了一些问题:当我试图调用的字符串版本AsNullIsEmpty时,编译器将我的字符串视为IEnumerable,当然返回类型错误 有没有办法对IEnumerable版本的定义设置一个“反约束”,这样我就可以告诉编译器在T的类型不是字符串时使用这个约束?差不多 public static IEnumerable<T> AsNullIfEmpty(this IEnu

受此启发,我正在尝试为
字符串
对象以及
IEnumerable
接口编写两个扩展方法,以简化null或emtpy检查。但是,我遇到了一些问题:当我试图调用
字符串
版本AsNullIsEmpty
时,编译器将我的字符串视为
IEnumerable
,当然返回类型错误

有没有办法对
IEnumerable
版本的定义设置一个“反约束”,这样我就可以告诉编译器在
T
的类型不是
字符串时使用这个约束?差不多

public static IEnumerable<T> AsNullIfEmpty(this IEnumerable<T> items)
    where T !: string
公共静态IEnumerable AsNullIfEmpty(此IEnumerable项)
哪里有T!:一串
我知道我可以更改其中一个的名称,但为了保持一致性,我希望使用相同的名称


更新:事实证明,我的扩展方法问题是通过另一种方式解决的,修复了一个简单而愚蠢的错误(我使用的是
str.IsNullOrEmpty()
,是
IEnumerable
上的扩展方法,而不是
string.IsNullOrEmpty(str)
)但是,由于泛型的反约束问题仍然是一个有趣的问题,我不会删除它。

唯一的方法是创建一个超负荷的扩展,它接受一个
字符串作为它的
这个
参数

public static string AsNullIfEmpty(this string value)
这样做会使特定类型的版本被认为是比泛型版本更好的重载匹配

至于您的具体问题(“我可以在泛型类型参数上指定“反约束”吗?”),答案是否定的。不过,您可以非常接近
过时的属性

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

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

这就是我遇到的问题,正如您在更新中看到的,扩展方法问题已经解决。(由于另一个错误而存在问题…)。但是,有没有办法指定反约束?那么当T是字符串时,两个具有相同签名的方法的智能性就很好了。@Tomas:有一个简单的答案:没有,没有办法指定反约束。@Tomas:请参阅我的编辑。严格的回答是“否”,但最终结果是可能的。编译器将采用最具体的可用方法。如果您实现了一个字符串,并确保它在呼叫站点上可用,那么您将不会遇到与前面描述的相同的问题