Serializing anonymous delegates in C#

前端 未结 6 1397
我在风中等你
我在风中等你 2020-12-01 02:59

I am trying to determine what issues could be caused by using the following serialization surrogate to enable serialization of anonymous functions/delegate/lambdas.

相关标签:
6条回答
  • 2020-12-01 03:17

    A function map would prevent me from using local state in the action/conditions. The only way around this would work would be to create a class per function that required additional state.

    This is what the C# compiler is doing automatically for me with anonymous functions. My issue is the serialization of these compiler classes.

            Other o = FromSomeWhere();
            Thing t = OtherPlace();
            target.OnWhatever = () => t.DoFoo() + o.DoBar();
            target.Save();c
    

    Trying to serialize that would fail. Since this state is local though that leads to issues when trying to setup a mapping. Instead I'd have to declare something like this:

    [Serializable]
    abstract class Command<T>
    {
        public abstract T Run();
    }
    
    class DoFooBar : Command<int>
    {
        public Other Other { get; set; }
        public Thing Thing { get; set; }
    
        public override int Run()
        {
            return Thing.DoFoo() + Other.DoBar(); 
        }
    }
    

    and then use it like this:

            DoFooBar cmd = new DoFooBar();
            cmd.Other = FromSomewhere();
            cmd.Thing = OtherPlace();
    
            target.OnWhatever = cmd.Run;
    
            target.Save();
    

    Essentially what this means is doing manually what the C# compiler is doing for me automatically.

    0 讨论(0)
  • 2020-12-01 03:19

    Did you see this post that I wrote as a followup to the CountingDemo: http://dotnet.agilekiwi.com/blog/2007/12/update-on-persistent-iterators.html ? Unfortunately, Microsoft have confirmed that they probably will change the compiler details (one day), in a way that is likely to cause problems. (e.g. f/when you update to the new compiler, you won't be able to deserialise the stuff you saved under the old (current) compiler.)

    0 讨论(0)
  • 2020-12-01 03:20

    I'm not 100% on this, but I believe that if you want to "save" a delegate or some code to the database that can be fairly dynamic, what you need to do is create an Expression, then you can compile the expression into a Func<...>.

    Expression Tree Basics

    Late Bound Invocations with Expression Trees

    0 讨论(0)
  • 2020-12-01 03:35

    Some objects need execute arbitrary "events" reaching some condition.

    Just how arbitrary are these events? Can they be counted, assigned ID's and mapped to referentially?

    public class Command<T> where T : ISerializable
    {
      T _target;
      int _actionId;
      int _conditionId;
    
      public Command<T>(T Target, int ActionId, int ConditionId)
      {
        _target = Target;
        _actionId = ActionId;
        _conditionId = ConditionId;
      }
    
      public bool FireRule()
      {
        Func<T, bool> theCondition = conditionMap.LookupCondition<T>(_conditionId)
        Action<T> theAction = actionMap.LookupAction<T>(_actionId);
    
        if (theCondition(_target))
        {
          theAction(_target);
          return true;
        }
        return false;
      }  
    }
    
    0 讨论(0)
  • 2020-12-01 03:36

    Since this state is local though that leads to issues when trying to setup a mapping.

    Wouldn't local state present the exact same problems for serialization?

    Suppose the compiler and the framework allowed this to work:

    Other o = FromSomeWhere();
    Thing t = OtherPlace();
    target.OnWhatever = () => t.DoFoo() + o.DoBar();
    target.Save();
    

    I guess t and o had to be serialized too. The methods don't have the state, the instances do.

    Later, you deserialize target. Don't you get new copies of t and o? Won't these copies be out of sync with any changes to the original t and o?

    Also: couldn't your manual example be called this way?

    Other o = FromSomeWhere();
    Thing t = OtherPlace();
    target.OnWhatever = new DoFooBar() {Other = o, Thing = t} .Run;
    target.Save();
    
    0 讨论(0)
  • The whole idea of serializing a delegate is very risky. Now, an expression might make sense, but even that is hard to express - although the dynamic-LINQ samples go some way to allowing a form of text-based expression.

    What exactly is it you want to do with a serialized delegate? I really don't think this is a good idea...

    0 讨论(0)
提交回复
热议问题