5

この例では、Foo.Something と Bar.Something の間に効果的な違いはありますか?

class Foo
{
    public string Something;
}

class Bar
{
    public string Something{get; set;}
}

class Program
{
    static void Main(string[] args)
    {
        var MyFoo = new Foo();
        MyFoo.Something = "Hello: foo";
        System.Console.WriteLine(MyFoo.Something);

        var MyBar = new Bar();
        MyBar.Something = "Hello: bar";
        System.Console.WriteLine(MyBar.Something);
        System.Console.ReadLine();
    }
}

私の知る限り、それらはまったく同じように動作します。もしそうなら、Foo のように単純なフィールドを使用しないのはなぜですか? Java では、セッターを使用して、コードを壊さずに新しい不変条件を強制し、ゲッターを使用して安全なデータを返しますが、c# では、いつでも Foo を次のように書き換えることができます。

class Foo
{
    private string _Something;
    public string Something
    {
        get { 
            //logic
            return _Something; 
            }
        set { 
            //check new invariant
            _Something = value; 
            }
    }
}

そして、古いコードは壊れません。

4

5 に答える 5

11

私の知る限り、それらはまったく同じように動作します。

いいえ、そうではありません。

  • フィールドはデータ バインディングでは使用できません (少なくとも一部のバインディングの実装では)。
  • ソースまたはバイナリの互換性を損なうことなく、後でプロパティのロジックを追加できます
  • プロパティは参照渡しできません
  • 自動的に実装されたプロパティに初期化子を追加することはできません
  • それらは反射の点で明らかに異なります
  • 哲学的には、プロパティは論理的に API の一部ですが、フィールドは実装の詳細です

c# では、いつでも Foo を次のように書き換えることができます: [...]

バイナリやソースの互換性を気にしないのであれば、そうすることができます。それがまったく問題にならない場合もあれば、非常に大きな問題になる場合もあります。最初から実装の詳細ではなく、API を公開することを選択してみませんか? { get; set; }コードを追加することで混乱が生じるわけではありません...

詳細については、これに関する私の記事を参照してください。

于 2013-03-21T15:01:31.773 に答える
1

Foo.SomethingはフィールドでBar.Something、自動的に実装されるプロパティです。それは大きな違いです。

フィールドと同じ方法でプロパティにアクセスできますが、プロパティにアクセスすると内部的に set/get メソッドが呼び出されます。

したがって、 と言うmyBar.Something = "asdf"と、C# コンパイラはこれをセッター メソッドの呼び出しに変換しますmyBar.set_Something("asdf")。setter メソッドと getter メソッドが自動的に生成され、実際の値のバッキング フィールドも生成されます。

get および set メソッドを使用してプロパティに変更Foo.Somethingすると、バイナリ互換性が失われます。つまりFoo.Something、フィールドがまだフィールドであったときに使用されていたすべてのアセンブリを再コンパイルする必要があります。

于 2013-03-21T15:00:04.693 に答える
0

public string Something{get; set;}単なる構文糖衣です。コンパイラは実際にこれをメソッドに拡張します。get; set;したがって、それのためだけに、すべてのフィールドをあちこちに配置することにはほとんど意味がありません。

于 2013-03-21T15:01:58.923 に答える
0

1) プライベート アクセサーを追加して、プロパティへのアクセスを取得または設定および制御できます。

public object MyProp {get; private set;}

どこでも小道具を読むことができますが、クラス内でのみ書くことができます

2)いくつかのロジックを読み取り/書き込みプロパティに接続できます。フィールドの場合、追加の操作はできません

3) フィールドをシリアライズすることはできません

于 2013-03-21T15:01:49.870 に答える
0

プロパティのゲッターとセッター (自動のものを含む) には、メソッド呼び出しコストがあります。アクセスで物事をきれいに保つために、パブリックフィールドは避けるべきです。

于 2013-03-21T15:00:03.273 に答える