gpt4 book ai didi

C# 6.0 空传播运算符和属性分配

转载 作者:IT王子 更新时间:2023-10-29 04:16:56 25 4
gpt4 key购买 nike

为了进行彻底的解释,这个问题已经过彻底修改。

我注意到 C# 6.0 中的 null 传播运算符似乎有一个很差的限制,因为您不能针对已被 null 传播的对象调用属性 setters(尽管您可以调用属性getters 针对已被 null 传播的对象)。正如您将从生成的 IL (我已将其反射(reflect)到 C# 中) 中看到的那样,没有任何东西应该限制使用 null 传播调用属性 setter 的能力。

首先,我创建了一个简单的类,它具有 Java 风格的 Get/Set 方法和一个具有公共(public) getter/setter 访问权限的属性。

public class Person
{
public Person(string name, DateTime birthday)
{
Name = name;
}

public string Name { get; set; }

public void SetName(string name)
{
Name = name;
}

public string GetName()
{
return Name;
}
}

我在下面的测试类中测试了null传播的能力。

public class Program
{
public static void Main(string[] args)
{
Person person = new Person("Joe Bloggs", DateTime.Parse("01/01/1991"));

// This line doesn't work - see documented error below
person?.Name = "John Smith";

person?.SetName("John Smith");

string name = person?.Name;
}
}

The left-hand side of an assignment must be a variable, property or indexer.

然而,您可能会注意到,通过调用 SetName(...) 设置名称的 Java 方法有效,您可能还会注意到获取 null 传播属性的值也有效.

让我们看一下从这段代码生成的 C#:

public static void Main(string[] args)
{
Person person = new Person("Joe Bloggs", DateTime.Parse("01/01/1991"));
if (person != null)
{
person.SetName("John Smith");
}
string arg_33_0 = (person != null) ? person.Name : null;
}

请注意,当用于 SetName 方法时,null 传播转换为简单的 if 语句,并且当用于 Name 属性时getter,三元运算符用于获取 Namenull 的值。

我在这里注意到的一件事是使用 if 语句和使用三元运算符之间的行为差​​异:使用 setter 时,使用 if 语句会起作用,而使用三元运算符则不会。

public static void Main(string[] args)
{
Person person = null;

if (person != null)
{
person.Name = "John Smith";
}

person.Name = (person != null) ? "John Smith" : null;
}

在这个例子中,我同时使用了 if 语句和三元运算符来检查 person 是否为 null,然后再尝试分配给它的 Name 属性(property)。 if 语句按预期工作;正如预期的那样,使用三元运算符的语句失败了

Object reference not set to an instance of an object.

在我看来,限制来自于 C# 6.0 将 null 传播转换为 if 语句或三元表达式的能力。如果它被设计为仅使用 if 语句,属性分配将通过 null 传播工作。

到目前为止,我还没有看到一个令人信服的论据来说明为什么这不应该是可能的,因此我仍在寻找答案!

最佳答案

你不是唯一一个! SLaks将其提升为 an issue (现在 here )

Why can't I write code like this?

Process.GetProcessById(2)?.Exited += delegate { };

在它被短暂关闭为“按设计”之后

the ?. Operator never produces an lvalue, so this is by design.

有人评论说它对属性 setter 和事件处理程序都有好处

Maybe add also properties setters into request like:

Object?.Prop = false;

它作为 C#7 的功能请求重新打开。

关于C# 6.0 空传播运算符和属性分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32519200/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com