私は多くの人がここで混乱していると思います。この特定の問題は、値型プロパティが(メソッドやインデクサーと同様に)値型のコピーを返し、値型フィールドが直接アクセスされることの理解に関連しています。次のコードは、プロパティのバッキングフィールドに直接アクセスすることで実現しようとしていることを正確に実行します(注:バッキングフィールドを使用して詳細形式でプロパティを表現することは、自動プロパティと同等ですが、コードでは次のような利点がありますバッキングフィールドに直接アクセスします):
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
myClass.SetOrigin();
Debug.Assert(myClass.Origin.X == 10); //succeeds
}
}
class MyClass
{
private Point _origin;
public Point Origin
{
get => _origin;
set => _origin = value;
}
public void SetOrigin()
{
_origin.X = 10; //this works
//Origin.X = 10; // fails with CS1612;
}
}
発生しているエラーは、プロパティが値型のコピーを返すことを理解していないことの間接的な結果です。値型のコピーが返され、それをローカル変数に割り当てない場合、そのコピーに加えた変更を読み取ることはできません。したがって、意図的に行うことはできないため、コンパイラーはこれをエラーとして生成します。コピーをローカル変数に割り当てると、Xの値を変更できますが、Xの値はローカルコピーでのみ変更され、コンパイル時のエラーを修正しますが、Originプロパティを変更するという望ましい効果はありません。次のコードは、コンパイルエラーがなくなったため、これを示していますが、デバッグアサーションは失敗します。
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
myClass.SetOrigin();
Debug.Assert(myClass.Origin.X == 10); //throws error
}
}
class MyClass
{
private Point _origin;
public Point Origin
{
get => _origin;
set => _origin = value;
}
public void SetOrigin()
{
var origin = Origin;
origin.X = 10; //this is only changing the value of the local copy
}
}