Suppose I have
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");
}
How do I change the target of the action? I’m OK to pass a delegate instead of action but its .Target is read-only, too.
Currently I think doing
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);
}
that is, switch from action to reflected method call… but it’s a bit ugly, isn’t it?
I have a feeling that the solution is very simple and I used to know it… just forgot.
Hm, one solution would be to have static delegate that accepts Entity as first parameter, but I wouldn’t want to go this way.
What you’re specifically asking for isn’t possible. A delegate represents a statically bound method, whereas you’re looking for something dynamic. To do that specifically you need reflection.
However, your code appears to be structured in the correct way to accomplish what you want, but the code doesn’t look like it’s being called correctly.
You define
actionasFunc<Entity, bool>, but you pass indata(which is anobject) rather thanchild(which is anEntity). It seems like you should actually declare it asFunc<Entity, object, bool>and do it like this: