我们可以节省代表们在一个文件中(C#) [英] Could we save delegates in a file (C#)

查看:95
本文介绍了我们可以节省代表们在一个文件中(C#)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有有代表成员的类。
我可以设置委托该类的每个实例化的对象,但一直没有找到任何方法来保存该对象尚未

I have a class which has a delegate member. I can set the delegate for each instantiated object of that class but has not found any way to save that object yet

推荐答案

这是做pretty冒险的事情。

This is a pretty risky thing to do.

虽然这是真的,你可以序列化和反序列化的委托,就像任何其他对象,委托是一个指针,它连载里面的程序的方法。如果您在另一个程序中反序列化对象,你会得到一个 SerializationException - 如果你是幸运的。

While it's true that you can serialize and deserialize a delegate just like any other object, the delegate is a pointer to a method inside the program that serialized it. If you deserialize the object in another program, you'll get a SerializationException - if you're lucky.

例如,让我们修改达林的计划了一下:

For instance, let's modify darin's program a bit:

class Program
{
   [Serializable]
   public class Foo
   {
       public Func<string> Del;
   }

   static void Main(string[] args)
   {
       Func<string> a = (() => "a");
       Func<string> b = (() => "b");

       Foo foo = new Foo();
       foo.Del = a;

       WriteFoo(foo);

       Foo bar = ReadFoo();
       Console.WriteLine(bar.Del());

       Console.ReadKey();
   }

   public static void WriteFoo(Foo foo)
   {
       BinaryFormatter formatter = new BinaryFormatter();
       using (var stream = new FileStream("test.bin", FileMode.Create, FileAccess.Write, FileShare.None))
       {
           formatter.Serialize(stream, foo);
       }
   }

   public static Foo ReadFoo()
   {
       Foo foo;
       BinaryFormatter formatter = new BinaryFormatter();
       using (var stream = new FileStream("test.bin", FileMode.Open, FileAccess.Read, FileShare.Read))
       {
           foo = (Foo)formatter.Deserialize(stream);
       }

       return foo;
   }
}

运行它,你会看到它创建的对象,其序列,反序列化到一个新的对象,当你调用删除新对象它返回A。优秀。好了,现在注释掉调用 WriteFoo ,使程序它只是反序列化对象。再次运行该程序,你会得到相同的结果。

Run it, and you'll see that it creates the object, serializes it, deserializes it into a new object, and when you call Del on the new object it returns "a". Excellent. Okay, now comment out the call to WriteFoo, so that the program it's just deserializing the object. Run the program again and you get the same result.

现在交换a和b的声明和运行程序。让人惊讶。现在,反序列化对象将返回B。

Now swap the declaration of a and b and run the program. Yikes. Now the deserialized object is returning "b".

这是因为发生了什么实际上正在连载的是,编译器分配给拉姆达前pression的名称。而编译器分配名称拉姆达前pressions中发现的顺序。

This is happening because what's actually being serialized is the name that the compiler is assigning to the lambda expression. And the compiler assigns names to lambda expressions in the order it finds them.

而这正是有风险这一点:你没有序列化的代表,你序列化的象征。这是的的符号,而不是符号重新presents,也被序列化。反序列化对象的行为取决于什么在节目中该符号重新presents说的反序列化它的价值。

And that's what's risky about this: you're not serializing the delegate, you're serializing a symbol. It's the value of the symbol, and not what the symbol represents, that gets serialized. The behavior of the deserialized object depends on what the value of that symbol represents in the program that's deserializing it.

要在一定程度上,这是所有的序列化如此。反序列化对象成不同实现对象的类比串行化程序做的,有趣的事情开始的程序。但是序列代表对夫妻的序列化对象到序列化它,而不是对象的类的实施方案的符号表中。

To a certain extent, this is true with all serialization. Deserialize an object into a program that implements the object's class differently than the serializing program did, and the fun begins. But serializing delegates couples the serialized object to the symbol table of the program that serialized it, not to the implementation of the object's class.

如果是我的话,我会考虑这种耦合明确。我想创建的静态属性,这是一个词典&LT;字符串函数功能:LT;串&GT;&GT; ,填充这个连键和功能,并存储在每一个实例,而不是功能键。这使负责填充字典中的反序列化程序启动反序列化对象之前。在某种程度上,这是完全一样的东西,使用的BinaryFormatter 连载委托所做的事。所不同的是,这种做法使得该符号很多更加明显分配功能反序列化程序的责任。

If it were me, I'd consider making this coupling explicit. I'd create a static property of Foo that was a Dictionary<string, Func<string>>, populate this with keys and functions, and store the key in each instance rather than the function. This makes the deserializing program responsible for populating the dictionary before it starts deserializing Foo objects. To an extent, this is exactly the same thing that using the BinaryFormatter to serialize a delegate is doing; the difference is that this approach makes the deserializing program's responsibility for assigning functions to the symbols a lot more apparent.

这篇关于我们可以节省代表们在一个文件中(C#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆