“不为空”和“!= null”有什么区别?

Paw*_*wel 50 c# c#-9.0

随着 C# 9.0 的发布,引入了否定空常量模式。

模式匹配的文档指出:

从 C# 9.0 开始,您可以使用否定 null 常量模式来检查非 null,如以下示例所示:

if (e is not null)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

除了语法之外,e is not null和之间还有什么区别吗?e != null

Kyl*_*e B 55

e != null和之间的主要区别e is not null在于编译器执行比较的方式。

Microsoft“编译器保证在计算表达式 x is null 时不会调用用户重载的相等运算符 ==。”

底线:如果您编写的代码不想依赖于某人对!=and==运算符的实现,请使用is nullandis not null因为它更安全。

请参见以下示例:

public class TestObject
{
  public string Test { get; set; }

  // attempt to allow TestObject to be testable against a string
  public static bool operator ==(TestObject a, object b)
  {
    if(b == null)
      return false;
    
    if(b is string)
      return a.Test == (string)b;

    if(b is TestObject)
      return a.Test == ((TestObject)b).Test;

    return false;
  }

  public static bool operator !=(TestObject a, object b)
  {
    if(b == null)
      return false;
    
    if(b is string)
      return a.Test != (string)b;

    if(b is TestObject)
      return a.Test != ((TestObject)b).Test;

    return false;
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您的代码需要确保对象不为 null,则 using会比 usingis not null提供更好的结果,因为/运算符的重载有点奇怪。TestObject!= null==!=

控制台示例1:

TestObject e = null;

if(e == null)
  Console.WriteLine("e == null");

if(e is null)
  Console.WriteLine("e is null");
Run Code Online (Sandbox Code Playgroud)

输出:e is null

控制台示例2:

TestObject e = new TestObject();

if(e != null)
  Console.WriteLine("e != null");

if(e is not null)
  Console.WriteLine("e is not null");
Run Code Online (Sandbox Code Playgroud)

输出:e is not null

两个重载运算符都没有“正确”实现,因此控制台永远不会输出e == nulle != null


mam*_*men 18

唯一的区别(除了语法之外)是,编译器保证在使用is not null代替!= null(或is null代替== null)时不会调用用户重载的运算符。

来自运算符重载

用户定义的类型可以重载预定义的 C# 运算符。也就是说,如果一个或两个操作数属于该类型,则该类型可以提供操作的自定义实现。可重载运算符部分 显示了哪些 C# 运算符可以重载。

  • 这不是**唯一**的区别 - 编译器在处理结构时不会让您使用 `x is null` 或 `x is not null` - 它会发出错误: *CS0037: Cannot conversion null to ' <your type>',因为它是不可为 null 的值类型*,但它会让您使用 `x == null` 或 `x != null` (带有警告 - *CS0472:表达式的结果始终是'false',因为类型 '<your type>' 的值永远不等于 'null'*)。 (3认同)
  • 在 C# 中,您可以重载运算符来更改它们的默认处理。有关详细信息,请参阅[运算符重载的官方文档](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/operator-overloading) (2认同)