【问题标题】:XML-Serializing delegatesXML 序列化委托
【发布时间】:2010-02-10 13:26:53
【问题描述】:

我有一个想要序列化的类,但它包含一个公开的委托实例,显然无法序列化:

<Serializable()> Class A
    Public Delegate Function TestEventHandler(ByVal myObj as CutomObject, _
                                         ByVal myObj2 as CustomObject) as Boolean

    ' does not 'want' to be serialized - cause: no parameterless constructor'
    Public TestDelegate as TestEventHandler
End Class

我使用了&lt;XmlIgnore()&gt; _,它有所帮助——我的意思是这个成员不再有例外。

有没有办法让它可序列化?

【问题讨论】:

    标签: .net vb.net .net-2.0 xml-serialization


    【解决方案1】:

    在委托上使用[XmlIgnore]


    不,没有办法序列化委托。它会是什么样子? .NET 以外的平台会用它做什么?

    【讨论】:

      【解决方案2】:

      您可以尝试在 4.0 中使用 Func 委托。它们是可序列化的。

      【讨论】:

        【解决方案3】:

        你的问题是?

        委托不能被序列化是可以理解的,因为它可以被看作是一个“函数指针”而不是真正的数据。

        您可以通过将NonSerialized 属性应用于该委托来解决您的问题。

        [Serializable]
        public class Test
        {
            [NonSerialized]
            public TestEventHandler TestDelegate;
        }
        

        但是,请记住,Xml 序列化需要其他属性,然后通过 BinaryFormatterSoapFormatter 类进行“常规”序列化。

        当你使用 XmlSerialization 时,你应该使用XmlIgnore 属性。 当您使用 XmlSerialization 时,您不必将您的类标记为 Serializable。 相反,它应该有一个默认的公共构造函数。 XmlSerialization 仅序列化具有 getter 和 setter 的公共属性。
        您可以通过 these attributes 的 XmlSerialization 控制对象的序列化方式。

        【讨论】:

        • 我使用 XmlSerialization,所以 NonSerialized 没有帮助。我使用了 _ 并且它有所帮助。现在,是否有可能序列化委托?
        • @Frederik: [NonSerialized] 不适用于 XML 序列化。
        • 这就是我要说的:XmlSerialization 和常规序列化是有区别的。从 Topicstarts openingpost,当我回答问题时,并不清楚他使用了什么样的序列化。
        【解决方案4】:

        您还必须将要调用的委托或方法的名称作为字符串存储在类中。

        我使用它是因为我想在配置文件中配置通过ftp下载文件后要调用的函数,即不同的ftp下载配置通过调用配置的方法(委托)以不同的方式处理下载的文件。

        public delegate string ProcessDownloadedFile(string filename);       
        
                //HACK: Cannot serialise delegates.
                public string ProcessDownloadFileMethod { get; set; }
        
                //HACK: Cannot serialise delegates.
                [XmlIgnore]
                public ProcessDownloadedFile ProcessFile { get; set; }
        

        然后当你想使用委托时,在这种情况下,我已经下载了文件。我使用存储在序列化配置文件中的字符串创建委托。

         //Create the delegate method if it has been set.
         if (!String.IsNullOrEmpty(ftpReceive.ProcessDownloadFileMethod) && ftpReceive.ProcessFile == null)
         {
         //Create the delegate.
         Type t = typeof(FTPTransfer);
         ftpReceive.ProcessFile = (FTPTransfer.ProcessDownloadedFile) Delegate.CreateDelegate(typeof(FTPTransfer.ProcessDownloadedFile), t.GetMethod(ftpReceive.ProcessDownloadFileMethod));
         }
        

        因此,理想情况下,您希望将要调用的函数/委托的名称存储为字符串,然后在运行时使用反射从字符串中创建它。

        希望这会有所帮助。

        或者,如果要调用的方法只存在于一个类中,您可以通过包装属性来简化它。

         //HACK: Cannot serialise delegates.
         public string ProcessDownloadFileMethod { get; set; }
        
         //HACK: Cannot serialise delegates.
         private ProcessDownloadedFile _processFile;
         [XmlIgnore]
         public ProcessDownloadedFile ProcessFile
         {
           get
           {
             if (_processFile == null && !String.IsNullOrEmpty(ProcessDownloadFileMethod))
             {
                Type t = this.GetType();
                this._processFile = (ProcessDownloadedFile) Delegate.CreateDelegate(typeof(ProcessDownloadedFile), t.GetMethod(this.ProcessDownloadFileMethod));
        
              }
              return _processFile;
            }
            set
              {
                 if (value != null)
                 {
                    ProcessDownloadFileMethod = value.Method.Name;
                 } else {
                    ProcessDownloadFileMethod = null;
                 }
                 _processFile = value;
               }
            }
        

        要真正做到这一点,最好包含类/类型以及用于创建委托的函数/方法名称。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-27
          • 2010-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多