【问题标题】:Can I serialize an object if I didn't write the class used to instantiate that object?如果我没有编写用于实例化该对象的类,我可以序列化一个对象吗?
【发布时间】:2010-04-15 14:17:32
【问题描述】:

我有一个简单的课程

[Serializable]
public class MyClass
{
  public String FirstName { get; set: }
  public String LastName { get; set: }

  //Bellow is what I would like to do
  //But, it's not working
  //I get an exception
  ContactDataContext db = new ContactDataContext();

  public void Save()
  {
   Contact contact = new Contact();
   contact.FirstName = FirstName;
   contact.LastName = LastName;

   db.Contacts.InsertOnSubmit(contact);
   db.SubmitChanges();
  }
}

我想为类附加一个 Save 方法,以便我可以在每个对象上调用它。当我引入上面包含 ContactDataContext 的语句时,我收到以下错误“In assembly ... PublicKeyToken=null' is notmarked as serializable

很明显DataContext类是由framework()生成的。我检查并没有看到那个类被标记为 serialize

我能做些什么来克服它?当我不是课程的作者时,规则是什么? 继续将 DataContext 类标记为可序列化,然后假装一切正常?

感谢您的帮助

【问题讨论】:

    标签: asp.net-mvc linq-to-sql serialization


    【解决方案1】:

    也许值得退后一步,看看你想要实现的目标是否真的有效。

    通常,可序列化的类用于两层之间的数据传输。它更有可能是一个只保存数据的简单类。

    它拥有持久化到数据库的能力似乎有点不合适。管道的两端实际上不可能访问数据库,而且它们似乎都不太可能具有持久化数据的能力。

    我想知道是否值得将保存到存储库中。所以有一个存储库类,它将接受数据传输对象,构造数据库对象并保存它。

    这将简化您的代码并完全避免您遇到的问题。它还将大大提高可测试性。

    【讨论】:

      【解决方案2】:

      问题在于db 字段被序列化,而显然它不需要被序列化(它在对象创建后被实例化)。

      因此,您应该使用NonSerialized 属性来装饰它:

      [NonSerialized] 
      ContactDataContext db = new ContactDataContext();
      

      [更新]

      为确保 db 字段在对象初始化后可访问,您应该使用 lazy loading property 并使用此属性而不是字段:

      [NonSerialized] 
      ContactDataContext db = null;
      
      [NonSerialized] 
      private ContactDataContext {
          get {
              if (db == null) {
                  db = new ContactDataContext();
              }
              return db;
          }
          set {
              db = value;
          }
      }
      
      public void Save()
      {
          Contact contact = new Contact();
          contact.FirstName = FirstName;
          contact.LastName = LastName;
      
          Db.Contacts.InsertOnSubmit(contact);
          Db.SubmitChanges();
      }
      

      [更新2]

      您可以序列化大多数对象,只要它具有公共无参数构造函数(或根本没有构造函数)并且没有无法序列化但需要序列化的属性/字段。如果类本身未标记为[Serializable],那么您可以使用部分类自己执行此操作。如果该类具有无法序列化的属性/字段,那么您可以通过继承该类并覆盖这些属性/字段以将它们装饰为[NonSerialized] 来实现这一点。

      【讨论】:

      • @PrutsWonder - 您的回答允许摆脱异常。现在我知道在序列化之前我需要先考虑一下,为此我感谢你。但是,我仍然想知道我没有写的课程的规则是什么。我是否用序列化属性装饰该类?
      • 不幸的是,db.InsertOnSubmit 正在产生“对象未设置为对象的实例”异常。还有什么可以做的吗?
      • 用可能的解决方案更新了答案。
      • 非常感谢。它现在正在工作。在让你走之前(接受你的帖子作为我问题的答案),告诉我是否可以序列化我没有写的课程。
      【解决方案3】:

      您可以创建一个知道如何序列化狡猾的类的代理 - 请参阅 here 以获取示例

      【讨论】:

        【解决方案4】:

        我认为您确实需要装饰基类,但是,DataContext 自动生成的类被标记为partial。您是否尝试过类似的操作:

        [Serializable]
        public partial class ContactDataContext
        {
        }
        

        不确定它是否会起作用,但值得一试。

        【讨论】:

          猜你喜欢
          • 2023-03-24
          • 1970-01-01
          • 2020-11-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-07
          相关资源
          最近更新 更多