2

プロパティのゲッターまたはセッターを参照する高性能な方法があるかどうか疑問に思っています。たとえば、以下の 2 番目のサンプル クラスの詳細をどのように入力しますか?

public class Example
{
    public Example()
    {
        Action<int> setter = SetX;
        Func<int> getter = GetX;
    }
    public int GetX() { return 0; }
    public void SetX(int value){}
}

public class Example2
{
    public Example2()
    {
        Action<int> setter = ...;
        Func<int> getter = ...;
    }
    public int X
    {
        get{ return 0; }
        set{}
    }
}

次のようにラムダを自分で作成できることはわかっていますAction<int> setter = x => X = x。ただし、これを行う理由の 1 つは、アプリケーションの他の部分で参照自体を比較することです。したがって、実際には参照を使用して特定のプロパティを識別したいと考えています。

たとえば、これを成功させたいと思います:

var example = new Example();
Func<int> something = example.GetX;
Func<int> somethingElse = example.GetX;
bool equality = something.Equals(somethingElse);

プロパティを使用する場合のみ。

これはリフレクションで実現できると思いますが、これらの操作の多くはアプリケーション全体で 1 秒間に 30 回ほど発生する可能性が高いため、GetX メソッドと SetX メソッドを宣言するだけでなく、そのようなソリューションを使用することをためらっています。不器用に思えても。

最終的な目標は、フィールドを設定し、リンクされている人にフィールドが設定されたことを通知し、それを達成するために文字列を使用しないようにする、構文的に単純な方法を作成することです。プロパティを使用しない例を次に示しますが、リンクは追加の抽象化で作成されます

public class Example
{
    public event Action<Delegate> Change;

    int x = 0;
    public int GetX() { return x; }
    public void SetX(int value) 
    {
        SetField(ref x, value, GetX);
    }

    protected void SetField<T>(ref T t, T value, Func<T> getter)
    {
        if (!EqualityComparer<T>.Default.Equals(getter(), value))
        {
            t = value;
            if(Change != null)
                Change(getter);
        }
    }
}

var example = new Example();
example.Change += getter =>
{
    Func<int> getX = example.GetX;
    if (getter.Equals(getX)) 
    {
        this.Log("x changed to: " + getX());
    }
};

example.SetX(5); // change is logged
4

1 に答える 1

4

リフレクションがこれを行う唯一の方法だと思います:

public Example2()
{
    var prop = this.GetType().GetProperty("X");
    Action<int> setter = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>), this, prop.GetSetMethod());
    Func<int> getter = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), this, prop.GetGetMethod());
}

しかし、あなたが言ったように、反映は特に高速ではありません。内部ゲッター/セッターをメソッドとして定義し、それらにバインドすることもできますが、それはまさにあなたが求めていたものではありません:

public Example2()
{
    Action<int> setter = this.GetX;
    Func<int> getter = this.SetX;
}

private int GetX() { return 0; }
private void SetX(int value) { }

public int X 
{
    get { return GetX(); } 
    set { SetX(value); } 
}
于 2013-05-08T17:16:10.850 に答える