更改C#操作/委托目标:分层调用

时间:2009-10-29 14:51:15

标签: c#

假设我有

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作为第一个参数,但我不想这样做。

2 个答案:

答案 0 :(得分:4)

您具体要求的内容是不可能的。委托表示静态绑定方法,而您正在寻找动态的东西。要做到这一点,你需要反思。

但是,您的代码似乎以正确的方式构建,以完成您想要的内容,但代码看起来并没有被正确调用。

您将action定义为Func<Entity, bool>,但是传入dataobject}而不是childEntity }})。看起来您应该将其声明为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之前只调用一次。