3

クラスを考えてみましょう:

public class foo
{
    public object newObject
    {
        get
        {
            return new object();
        }
    }
}

MSDNによると:

プロパティは、プライベート フィールドの値を読み取り、書き込み、または計算するための柔軟なメカニズムを提供するメンバーです。プロパティは、パブリック データ メンバーであるかのように使用できますが、実際にはアクセサーと呼ばれる特別なメソッドです。これにより、データに簡単にアクセスできます

と:

プロパティを使用すると、実装または検証コードを隠しながら、値を取得および設定するパブリックな方法をクラスで公開できます。

get プロパティ アクセサーはプロパティ値を返すために使用され、set アクセサーは新しい値を割り当てるために使用されます。これらのアクセサーは、異なるアクセス レベルを持つことができます。詳細については、アクセサーのアクセシビリティを参照してください。

value キーワードは、セット インデクサーによって割り当てられる値を定義するために使用されます。

set メソッドを実装しないプロパティは読み取り専用です。メソッドの安全性と柔軟性を提供しながら。

したがって、これはある時点で newObject プロパティの値が返された新しいオブジェクトへの参照を持つことを意味するのでしょうか?

編集はプロパティから読み取り専用を削除しました

edit2はまた、これがプロパティの最適な使用法ではなく、質問をより効果的に説明するために行われたことを明確にしたいと考えています。

4

4 に答える 4

10

プロパティにアクセスするたびに新しいオブジェクトを返しますが、これはプロパティの期待される動作ではありません。代わりに、毎回同じ値を返す必要があります (たとえば、フィールドに格納された値)。プロパティ ゲッターは、値を返すメソッドの単純な美化された構文です。コードは次のようにコンパイルされます (コンパイラはプロパティ名のプレフィックスを付けてゲッターを作成し、get_IL として出力します)。

public class foo
{
    public object get_newObject()
    {
        return new object();
    }
}

fooゲッターを呼び出すたびに、認識していない、またはアクセスできる新しいオブジェクトが作成されます。

したがって、これはある時点で newObject プロパティの値が返された新しいオブジェクトへの参照を持つことを意味するのでしょうか?

いいえ。


バッキング フィールドを使用するプロパティ:

class Foo {

  readonly Object bar = new Object();

  public Object Bar { get { return this.bar; } }

}

自動プロパティの使用:

class Foo {

  public Foo() {
    Bar = new Object();
  }

  public Object Bar { get; private set; }

}

プロパティには、パブリック フィールドと同じ簡単な構文を使用してアクセスします。ただし、プロパティを使用することで、getter と setter にコードを追加して、getter での遅延読み込みや setter での検証 (およびその他の多く) などを行うことができます。

于 2012-06-06T15:37:14.570 に答える
1

C# のプロパティは「シンタックス シュガー」です。getプロパティのブロック内のコードは、実際には非表示get_PropertyName()のメソッドに配置され、setブロックは非表示のメソッドに配置されset_PropertyName()ます。コードの場合、次のメソッドが作成されます。

public object get_newObject()
{
    return new object();
}

Reflector または ildasm を使用してコンパイルされたアセンブリを表示すると、これらの非表示のメソッドを確認できます。

プロパティが使用されると、C# コンパイラはプロパティの "get" アクセスをメソッドの呼び出しに変換しますget_newObject()。例として:

次のように書くとします。

var foo = new foo();
var aNewObject = foo.newObject;

コンパイラはそれを次のように変換します。

var foo = new foo();
var aNewObject = foo.get_newObject();

したがって、他の質問への回答として、誰かがプロパティを「取得」したときに返される新しく作成されたオブジェクトは、foo インスタンス内に格納されず、呼び出し元は毎回新しいオブジェクトを取得するだけです。

于 2012-06-06T15:47:28.913 に答える
1

内部的には、プロパティは次のような get_newObject() という名前の関数を呼び出すだけです。

public object get_newObject()
{
    return new object();
}

そのため、呼び出されるたびに常に新しいオブジェクトが返されます。

オブジェクトへの参照を保持したい場合は、次のように、データを保持するプライベート フィールドを作成し、プロパティにそのフィールドにアクセスさせることをお勧めします。

private object myObject;
public object newObject
{
    if(myObject == null)
    {
        myObject  = new object();
    }
    return myObject;
}

あなたのプロパティはセットを定義しておらず、あなたのフィールドはプライベートであるため、 newObject は基本的に、含まれているクラスの外部でのみ消去されます。

于 2012-06-06T15:46:05.523 に答える
0

ではない正確に。プロパティは単なるシンタックス シュガーであるため、アクセサ メソッド (Java など) を記述する必要はありません。

したがって、この:

private int _myInteger;
public int MyInteger
{
    get { return _myInteger; }
    set { _myInteger = value; }
}

はこれと同等です:

private int _myInteger;
public int GetMyInteger()
{
    return _myInteger;
}

public void SetMyInteger(int value)
{
   _myInteger = value;
}

そしてこれで良くなり、これも同等です:

public int MyInteger { get; set; }
于 2012-06-06T15:38:30.700 に答える