我想知道是否有一种高效的方式来引用属性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
答案 0 :(得分:3)
我认为反思是唯一的方法:
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); }
}