使这个反射方法调用类型安全
-
01-10-2019 - |
题
class CustomerMessage
{
private string name;
private Dictionary<MethodBase, object> changeTrackingMethods =
new Dictionary<MethodBase, object>();
public int Id { get; set; }
public string Name {
get { return this.name; }
set
{
this.name = value;
this.PropertyChanged("SetName", value);
}
}
private void PropertyChanged(string behaviorMethod, object value)
{
var method = typeof(Customer).GetMethod(behaviorMethod);
this.changeTrackingMethods.Add(method, value);
}
public void ApplyChanges(Customer c)
{
foreach (var changedProperty in this.changeTrackingMethods)
changedProperty.Key.Invoke(c, new object[] {
changedProperty.Value
});
}
}
正如您所看到的,我正在跟踪此传入消息的更改,以在另一个对象上运行更改。要运行的方法作为字符串传递给 PropertyChanged。有谁知道如何使这种类型安全吗?
解决方案
这样的东西?
class CustomerMessage
{
private string name;
private List<Action<Customer>> changeTrackingMethods =
new List<Action<Customer>>();
public int Id { get; set; }
public string Name {
get { return this.name; }
set
{
this.name = value;
this.changeTrackingMethods.Add(c => { c.SetName(value) });
}
}
public void ApplyChanges(Customer c)
{
foreach (var action in this.changeTrackingMethods)
{
action(c);
}
}
}
其他提示
因此,您想避免将方法名称作为字符串传递?为什么不将Methodbase对象放在设置器中?
public string Name {
get { return this.name; }
set
{
this.name = value;
this.PropertyChanged(typeof(Customer).GetMethod(behaviorMethod), value);
}
}
private void PropertyChanged(MethodBase method, object value)
{
this.changeTrackingMethods.Add(method, value);
}
您可以存储应执行的委托,而不是将“需要完成的操作”存储为一对方法和应使用反射传递给它的参数。最简单的方法是存储类型列表 List<Action<Customer>>
- 然后在 ApplyChanges
方法,您可以迭代列表并运行所有操作。
如果您不使用 .NET 3.5 和 C# 3.0(定义了通用委托) Action
并且支持 lambda 表达式),您仍然可以在 C# 2.0 中编写:
// you can define a delegate like this
delegate void UpdateCustomer(Customer c);
// and you could use anonymous methods
// (instead of more recent lambda expressions)
list.Add(delegate (Customer c) { c.SetName("test"); });
编辑:看起来我编写代码的速度较慢,但我将其保留在这里作为解释 - 'dtb' 的解决方案完全按照我所描述的方式进行。
不隶属于 StackOverflow