c# - 将泛型与可能是值或引用类型的 null 进行比较?

标签 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,因为我不想限制 ValueType 等于它的 default(T)。我的代码以这种方式编译和工作得很好(ReSharper 提示,但 CodeAnalysis 没有)。虽然我确实想知道:

  • 是否有更标准的方法来处理这种情况?
  • 是否有可能由此引发问题?
  • 当我调用并传入一个值类型时,幕后到底发生了什么?

最佳答案

I'm purposely only checking against null because I don't want to restrict a ValueType from being equal to its default(T)

这是一个很好的见解,但别担心,您已经了解了这些内容。首先使用 == 将 T 与 default(T) 进行比较是不合法的;重载解析不会找到唯一的最佳 == 运算符。

当然,您可以使用 .Equals 进行比较,但是如果接收者为空,您将面临崩溃的风险,这正是您试图避免的。

Is there a more standard way to handle this situation?

没有。与 null 进行比较是正确的做法。

正如 C# 规范在第 7.10.6 节中所说:“x == null 构造是允许的,即使 T 可以表示值类型,并且结果被简单地定义为当 T 是值类型时为 false。"

Is there any chance of an issue arrising from this?

当然。仅仅因为代码编译并不意味着它具有您想要的语义。编写一些测试。

What truly happens under the hood when I make a call and pass in a value type?

这个问题是模棱两可的。让我改写成两个问题:

What truly happens under the hood when I make a call on the generic method with a type argument that is a non-nullable value type?

抖动会在第一次调用该构造时编译方法。当抖动检测到 null 检查时,它会将其替换为“false”,因为它知道任何不可为 null 的值类型都不会等于 null。

What truly happens under the hood when I make a call on the generic method with a type argument that is a reference type but an argument that is a struct type? For example:

interface IFoo : ISomeInterface<IFoo> {}
struct SFoo : IFoo { whatever }
...
DoFooInternal<IFoo>(new SFoo());

在那种情况下,抖动无法避免空值检查,调用站点也无法避免装箱。 SFoo 实例将被装箱,并且将检查对装箱 SFoo 的引用以查看它是否为空。

关于c# - 将泛型与可能是值或引用类型的 null 进行比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8823239/

相关文章:

c# - 查看 RadioButtonList 是否具有选定值的最佳方法是什么?

generics - Kotlin 绑定(bind)类型参数扩展重载

swift - 将 Int 转换为 Collection.IndexDistance

Java 泛型无法识别类型?

ios - Swift: fatal error :在初始化 UIlabel 值时展开可选值时意外发现 nil

spring - 当未找到 User 时,Spring @Service 应该返回什么?

javascript - "Cannot read property ' 匹配 ' of null"

c# - 有问题的 if 语句

c# - 谷歌图表和 asp.net MVC

javascript - 使用 selectize multiselect 将值传递给数据库