如何引用属性访问器和mutator (getter/setter)

本文关键字:mutator setter getter 属性 何引用 引用 访问 | 更新日期: 2023-09-27 18:12:36

我想知道是否有一种高性能的方式来引用属性getter或setter。例如,如何为

下面的第二个示例类填充详细信息?
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{}
    }
}

我知道我可以像这样自己创造lamdas: Action<int> setter = x => X = x。然而,我希望这样做的原因之一是比较应用程序其他部分中的引用本身。因此,我实际上希望使用引用来识别特定的属性。

例如,我想要这个成功:

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

只能使用属性

我认为这可以通过反射来完成,然而,在我的应用程序中,许多这些操作可能每秒发生30次左右,所以我犹豫是否使用这样的解决方案,而不是仅仅声明GetX和SetX方法,尽管这看起来很笨拙。

最终目标是创建一种语法简单的方法来设置字段,并通知那些已经链接的人它已经设置,并避免使用字符串来完成它。下面是一个不使用Properties的示例,但是可以通过附加抽象

创建链接。
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

如何引用属性访问器和mutator (getter/setter)

我认为反射是做到这一点的唯一方法:

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());
}

但是正如你所说,反射不是特别快。您可以将内部getter/setter定义为方法并绑定到它们,但这也不是您所要求的:

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); } 
}