假设我有
public IList<Entity> Children { get; set; }
public NotifyChildren(Func<object, bool> action, object data)
{
foreach (var child in Children)
if (action(data))
/// <-- !!!! need action to work on child this time, not on the original target
//child.NofifyChildren(action, data); <- this doesn't work because of the above requirement
child.NotifyChildren(action.ChangeTargetTo(child), data); // << pseudocode!
}
public void SomeChangeOccured()
{
var changedChild;
NotifyChildren(x => x.SomeHandler(), "somedata");
}
如何更改操作的目标?我可以传递委托而不是动作,但它的.Target也是只读的。 目前我认为正在做
public NotifyChildren(Expression<Func<Entity, bool>> action, object data)
{
// so that I can do method.Invoke(newtarget, new object[]{data});
NotifyChildren(((MethodCallExpression)action).Method, data);
}
也就是说,从动作切换到反射方法调用...但它是位丑陋,不是吗?
我有一种感觉,解决方案非常简单,我曾经知道它......只是忘了。
嗯,一个解决方案是让静态委托接受Entity作为第一个参数,但我不想这样做。
答案 0 :(得分:4)
您具体要求的内容是不可能的。委托表示静态绑定方法,而您正在寻找动态的东西。要做到这一点,你需要反思。
但是,您的代码似乎以正确的方式构建,以完成您想要的内容,但代码看起来并没有被正确调用。
您将action
定义为Func<Entity, bool>
,但是传入data
(object
}而不是child
(Entity
}})。看起来您应该将其声明为Func<Entity, object, bool>
,并按照以下方式执行:
public IList<Entity> Children { get; set; }
public NotifyChildren(Func<Entity, object, bool> action, object data)
{
foreach (var child in Children)
{
if (action(child, data))
{
child.NofifyChildren(action, data);
}
}
}
public void SomeChangeOccured()
{
NotifyChildren((x, data) => x.SomeHandler(data), "somedata");
}
public bool SomeHandler(object data)
{
return true; // obviously need more robust logic
}
答案 1 :(得分:0)
foreach (var child in Children)
if (action(data))
/// <-- !!!! need action to work on child this time, not on the original target
child.NofifyChildren(action, data);
为什么在此循环中调用动作?我想你可以在foreach之前只调用一次。