16

これは素朴に聞こえるかもしれませんが...

class Widget
{
    public int Foo { get; set; }
}

これはすばらしいことであり、バッキングフィールドを使用することで定型文を節約できますが、その時点では、単純に次のようになります。

class Widget
{
    public int Foo;
}

ボンネットの下では違って見えると思いますが、それは公の場に過ぎないようです。ただし、設計の観点から、カプセル化に役立たない場合にプロパティを使用する利点は何ですか?

4

6 に答える 6

24

クラスのメタデータを変更せずに、カプセル化されたロジックを後で追加できる可能性があるためです。

プロパティの使用はベストプラクティスと見なされます-自動的に実装されたプロパティは、開発者がこのベストプラクティスに従うように促すために、プロパティを作成する面倒な作業を取り除くように設計されています

于 2011-02-22T03:42:39.493 に答える
10

これまでに投稿された他の良い答えに加えて:

  • private-setter-public-getterプロパティをすばやく作成するのは簡単です。これは、不変のデータ型を作成するためのパブリック読み取り専用フィールドよりも間違いなく優れた方法です。
于 2011-02-22T03:55:15.317 に答える
2
  1. プロパティを使用すると、クラスにカプセル化を追加できます
  2. プロパティを選択すると、アクセスを多態的にすることができます(プロパティが仮想の場合、継承者はアクセスを変更できます)。
  3. 自動プロパティは、単純なget/set操作を処理する場合に便利です。get / set内でより複雑な操作を行う場合、自動プロパティを使用することはできません。

また、リフレクションはプロパティでの動作と変数での動作に違いはありませんが、MemberInfo(FieldInfo、PropertyInfo、またはMethodInfoのいずれかを選択した方法)を使用しています。

于 2011-02-22T05:12:50.643 に答える
0
  1. 何らかの理由でプログラマーが従う必要のあるある種の標準
  2. リフレクションは、プロパティと変数で異なる働きをします
  3. 変数に対してデータバインドすることはできません
  4. 変数をプロパティに変更する場合は、変数を使用したすべてのコードを再構築する必要があります
于 2011-02-22T03:47:08.377 に答える
0

msdnから:

プロパティは、フィールドとメソッドの両方の側面を組み合わせたものです。オブジェクトのユーザーには、プロパティはフィールドのように見えます。プロパティにアクセスするには、同じ構文が必要です。

あなたはこのようなことをすることができます:

public class Date
{
private int month = 7;  // Backing store

public int Month
{
    get
    {
        return month;
    }
    set
    {
        if ((value > 0) && (value < 13))
        {
            month = value;
        }
    }
}
}

簡単に言えば、プロパティははるかに用途が広いです。

于 2011-02-22T03:55:50.107 に答える
-1
  • ゲッターやセッターにカスタムロジックがない場合は、自動プロパティを使用します。

  • 自動プロパティは、「自動的に」「バッキングフィールド」も定義します。

これは、自動プロパティを実装するときに「内部」で起こっていることです。

あなたのクラス:

public class YourClass {
    public int Foo { get; set; }
}

ILコード:

.class private auto ansi '<Module>'
{
} // end of class <Module>

.class public auto ansi beforefieldinit YourClass
    extends [System.Private.CoreLib]System.Object
{
    // Fields
    .field private int32 '<Foo>k__BackingField'  //this is the backing field for your property
    .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
        01 00 00 00
    )

    // Methods
    .method public hidebysig specialname 
        instance int32 get_Foo () cil managed //this is the GETTER of your property
    {
        .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
            01 00 00 00
        )
        // Method begins at RVA 0x2050
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: ldfld int32 YourClass::'<Foo>k__BackingField'
        IL_0006: ret
    } // end of method YourClass::get_Foo

    .method public hidebysig specialname 
        instance void set_Foo (
            int32 'value'
        ) cil managed //this is the SETTER of your property
    {
        .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
            01 00 00 00
        )
        // Method begins at RVA 0x2058
        // Code size 8 (0x8)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: ldarg.1
        IL_0002: stfld int32 YourClass::'<Foo>k__BackingField'
        IL_0007: ret
    } // end of method YourClass::set_Foo

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x2061
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
        IL_0006: ret
    } // end of method YourClass::.ctor

    // Properties
    .property instance int32 Foo()
    {
        .get instance int32 YourClass::get_Foo()
        .set instance void YourClass::set_Foo(int32)
    }

} // end of class YourClass


こちらでも確認できます。

于 2021-05-13T08:19:46.030 に答える