この質問は、説明を徹底するために完全に見直されました。
null が伝播されたオブジェクトに対してプロパティセッターを呼び出すことができないという点で、C# 6.0 の null 伝播演算子の非常に貧弱な制限のように見えることに気付きました(ただし、null が伝播されたオブジェクトに対してプロパティゲッターを呼び出すことはできます) 。 . 生成された IL (これは C# に反映されています)からわかるように、null 伝播を使用してプロパティ セッターを呼び出す機能を制限するものは何もありません。
手始めに、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;
}
}
割り当ての左側は、変数、プロパティ、またはインデクサーでなければなりません。
ただし、このことから、名前を設定する Java の呼び出しによる方法がSetName(...)
機能することに気付くかもしれません。また、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
の値を取得するために三項演算子が使用されることに注意してください。Name
null
ここで気づいたことの 1 つは、ステートメントを使用する場合と三項演算子を使用する場合の動作の違いですif
。セッターを使用する場合、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
に機能します。if
期待どおり、三項演算子を使用するステートメントは失敗します
オブジェクト参照がオブジェクト インスタンスに設定されていません。
if
私の意見では、この制限は、NULL 伝搬をステートメントまたは三項式に変換する C# 6.0 の機能によるものです。ステートメントのみを使用するように設計されていた場合if
、プロパティの割り当ては null 伝播を介して機能します。
これまでのところ、これが可能であってはならない理由について説得力のある議論を見たことがありません。したがって、私はまだ答えを探しています!