2011-11-11 13 views

答えて

1

あなたが反射せずにそれにアクセスすることはできませんが、あなたの場合 - これは、あなたがそれを行うことができる方法である。理論的には

<MyProperty>k__BackingField 
Success 
1

構文はauto-implemented propertyです。 バッキング変数はコンパイラによって生成され、アクセスすることはできません。これは、コンパイラによって生成されますプライベートバッキングフィールドに格納する

private string __foo_1; // Compiler-generated - cannot access. 
public string ModifiedBy 
{ 
    get { return __foo_1; } 
    set { __foo_1 = value; } 
} 
+1

あなたは反射を通してそれにアクセスすることができます –

+1

@parapurarajkumar:はい、理論的には可能ですが、ほとんどのプログラムでは何も良いことはありません。 – BrokenGlass

+0

もちろん。しかし、なぜ自分でバッキング変数を追加するだけで、リフレクションの遅さを避けることができるのでしょうか?私の前提は、OPがC#でのプロパティの動作を完全に理解していないということでした。 –

3

:本質的のようなものにコンパイル

。フィールドは<ModifiedBy>k__BackingFieldのような名前ですが、反射で見つけることは可能ですが、必ずしもそうするのは良い考えではありません。

フィールドにアクセスする特定の理由がある場合は、定義されたバッキングフィールドを使用して明示的な実装を使用するようにプロパティを変更する必要があります。しかし定義上、自動プロパティはその値を保存して取得するだけなので、まだ複雑なgetterとsetterを使用していない場合は、そのフィールドにアクセスする必要はありません。

+2

変数の実際の名前は '_ModifiedBy'です。 – Ryan

+0

@minitech:フィールドの実際の名前は ' k__BackingField'です。私はこれを反映するために私の答えを更新しました。それを指摘してくれてありがとう。 – StriplingWarrior

+0

そうですが、_ModifiedByをどこかで使用しようとするだけで、動作するとは思えません。だからこそ私はそれをやめました。 –

7

はい、コンパイラはバッキングフィールドを生成します。

いいえ、コンパイル時にはアクセスできません。

はい、実行時にリフレクションでアクセスできます。

いいえ、そうしないでください。


プロパティのバッキングフィールドにアクセスする最も簡単な方法は、バッキングフィールドとプロパティを実装するために、当然、次のとおりです。あなたは、自動実装プロパティのしやすさが必要な場合

private int _myInt; 
public int MyInt { 
    get { return _myInt; } 
    set { _myInt = value; } 
} 

、しかし、誰もがその値を変更できるようにしたくない、すなわち

public int MyInt { get; private set; } // or protected set etc 
0

あなたができない、一つまたはそれの他の部分へのアクセス修飾子を制限することが適切かもしれません。しかし、なぜあなたはそれをやりたいのですか?速度の問題であれば、プロパティを使用する必要はありません。それ以外の場合は、自動実装されたプロパティのバッキング変数にアクセスする必要があることがわかります。なぜなら、これらのプロパティには副作用がなく、通常のフィールドとほとんど同じ機能を持つからです。

1

using System.Diagnostics; 
using System.Linq; 
using System.Reflection; 

class Program 
{ 
    internal class MyClass 
    { 
     public string MyProperty { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     foreach (var mi in 
       typeof(MyClass).GetMembers(BindingFlags.NonPublic | BindingFlags.Instance) 
        .Where(m => m is FieldInfo)) 
     { 
      Debug.WriteLine(mi.Name); 
     } 

     MyClass o = new MyClass(); 
     var fi = (FieldInfo)typeof(MyClass).GetMember(
      "<MyProperty>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic)[0]; 
     fi.SetValue(o, "Success"); 
     Debug.WriteLine(o.MyProperty); 
    } 
} 

これは、次のような出力を提供します public autoプロパティは、パブリック変数と同じです。既に多くの人々が言及したように。コンパイラはデータを保持するために必要なプライベート変数を作成します。基礎となるプライベート変数にアクセスする必要がある場合は、実行時例外を避けるために、ハードコードされた変数名に移動します。

しかし現実に我々は将来の発展がにこのアセンブリにdepentアプリケーションを壊さないことを確認するためにautoプロパティを作成する必要があります。

パブリック変数をプロパティに変更すると、breaking changeとなります。リンクされたブログを参照して、それをよりよく理解してください。

関連する問題