mic*_*ael 41 c# generics null value-type null-check
public void DoFoo<T>(T foo) where T : ISomeInterface<T>
{
    //possible compare of value type with 'null'.
    if (foo == null) throw new ArgumentNullException("foo");
}
我故意只检查null,因为我不想限制a ValueType等于它default(T).我的代码以这种方式编译和工作(ReSharper抱怨,但不是CodeAnalysis).虽然我想知道:
Eri*_*ert 54
我故意只是检查,
null因为我不想限制ValueType等于它default(T)
这是一个很好的见解,但不要担心,你已经被覆盖了.首先将T与default(T)使用进行比较是不合法的==; 重载决议不会找到唯一的最佳==运算符.
当然,您可以进行比较,.Equals但如果接收方为空,则会冒着崩溃的风险,这正是您试图避免的.
有没有更标准的方法来处理这种情况?
不.比较为null是正确的做法.
作为C#说明书中部分7.10.6说:" 该x == null构建体被允许即使Ť可以表示的值的类型,并且将结果简单地定义为假当T是一个值类型. "
有没有可能出现这个问题?
当然.仅仅因为代码编译并不意味着它具有您想要的语义.写一些测试.
当我打电话并传递值类型时,真正发生了什么?
这个问题含糊不清.让我把它改成两个问题:
当我使用类型参数作为非可空值类型调用泛型方法时,真正发生了什么?
抖动在第一次调用时使用该构造编译方法.当抖动检测到空检查时,它将其替换为"false",因为它知道没有非可空值类型将等于null.
当我使用作为引用类型的类型参数但作为结构类型的参数对泛型方法进行调用时,真正发生了什么?例如:
interface IFoo : ISomeInterface<IFoo> {}
struct SFoo : IFoo { whatever }
...
DoFooInternal<IFoo>(new SFoo());
在这种情况下,抖动不能忽略空检查,并且呼叫站点无法避免装箱.将对SFoo实例进行装箱,并检查对盒装SFoo的引用以查看它是否为空.
Nuf*_*fin 11
不,不会有任何问题,但如果您希望警告消失,您可以使用以下内容:
public void DoFoo<T>(T foo) where T : ISomeInterface<T>
{
    if (ReferenceEquals(foo, null)) throw new ArgumentNullException("foo");
}
或者你可以这样做:
// when calling this with an actual T parameter, you have to either specify the type
// explicitly or cast the parameter to T?.
public void DoFoo<T>(T? foo) where T : struct, ISomeInterface<T>
{
    if (foo == null)
    {
        // throw...
    }
    DoFooInternal(foo.Value);
}
public void DoFoo<T>(T foo) where T : class, ISomeInterface<T>
{
    if (foo == null)
    {
        // throw...
    }
    DoFooInternal(foo); 
}
private void DoFooInternal<T>(T foo) where T : ISomeInterface<T>
{
    // actual implementation
}
| 归档时间: | 
 | 
| 查看次数: | 4837 次 | 
| 最近记录: |