C# 为什么resharper会提出以下建议?

C# 为什么resharper会提出以下建议?,c#,resharper,C#,Resharper,我的代码是 public static void AssertNotNull<T>(string name, T val) { if (val == null) throw new ArgumentNullException(String.Format("{0} must not be null", name)); } publicstaticvoidassertnotnull(字符串名,T val){ if(val==null) 抛出新ArgumentNu

我的代码是

public static void AssertNotNull<T>(string name, T val) {
    if (val == null)
        throw new ArgumentNullException(String.Format("{0} must not be null", name));
}
publicstaticvoidassertnotnull(字符串名,T val){
if(val==null)
抛出新ArgumentNullException(String.Format(“{0}不能为null”,name));
}
Resharper正在推荐

public static void AssertNotNull<T>(string name, T val) {
    if (Equals(val, default(T)))
        throw new ArgumentNullException(String.Format("{0} must not be null", name));
}
publicstaticvoidassertnotnull(字符串名,T val){
if(等于(val,默认值(T)))
抛出新ArgumentNullException(String.Format(“{0}不能为null”,name));
}

因为它不知道
t
是值类型还是引用类型,所以它使代码可以同时使用这两种类型。

我支持Berado的回答,但要补充的是,您可以通过添加以下约束来防止这种情况:

public static void AssertNotNull<T>(string name, T val) where T : class
publicstaticvoidassertnotnull(字符串名,T val),其中T:class

这两种方法并不等同。第一个允许AssertNotNull(“foo”,0),而第二个允许抛出。我认为Resharper在这种情况下过于热心了。

这显然不是您在本例中想要的,但它只是试图提供帮助,确保您不会因为忘记引用类型可用于
t
而引入错误。如前所述,您可能希望将
class
约束添加到
T
,我想这是因为T可能是非引用类型。

如果您知道T始终是类,那么添加where子句来说明,那么您的原始代码就可以了

public static void AssertNotNull<T>(string name, T val)
    where T : class
    {
        if (val == null)
            throw new ArgumentNullException(String.Format("{0} must not be null", name));
    }
publicstaticvoidassertnotnull(字符串名,T val)
T:在哪里上课
{
if(val==null)
抛出新ArgumentNullException(String.Format(“{0}不能为null”,name));
}

因此,如果我想执行以下操作以确保它是ref类型,我应该为XXX添加什么?公共静态void AssertNotNull(字符串名,T val),其中T:XXXnm Michael Meadows回答说,在本例中,partI实际上不同意Resharper,如果这就是它给出错误的原因的话。试想一下,如果T是一个int,并且该值实际上是0并且应该是零,它将抛出一个异常,而如果您检查null,它不会抛出一个异常。这个建议肯定是错误的,但它确实需要标记它,因为这是一个静态代码错误。API不应允许值类型调用方法调用AssertNotNull。@jayrdub:“其中t:class”。然后你可以检查空值。正是这样的事情让resharper的价值翻了十倍。有趣的问题+1,只有一件事你能在标题中添加更多信息以便下次更容易找到吗?说“为什么resharper建议将val==null替换为Equals(val,default(T))”谢谢。你的观点是正确的。默认情况下,Resharper将其标记为警告(黄色)。它只是想警告您,对于所有可能的输入,此方法不会像预期的那样工作。呃,有一个修订:AssertNotNull(“foo”,0)不会引发异常,它会像一个空值一样工作,因为int的默认值是0,因此Equals(val,default(t))的计算结果为true。我的意思是“抛出新的ArgumentNullException”将在第二个方法中运行。你同意吗?