【问题标题】:Loading polymorphics objects - need pattern加载多态对象 - 需要模式
【发布时间】:2009-12-04 05:31:43
【问题描述】:

我需要一些漂亮的方法来加载多态对象

我有基类和几个基类不知道的派生类。唯一的事情 基类知道是类型枚举,它定义了它是哪个实际类。

class Order
{
 OrderType Type;

 bool Load(string filename)
 {
   // load Type
 }
}

class LimitOrder : Order
{

 // some data
 bool Load(string filename)
 {
   // load some data
 }
}

我需要为基类 Order 编写一个 Load 方法,它可以正确地创建相应的派生类。 我正在寻找一个好的模式。

【问题讨论】:

  • 看起来您正在创建自定义序列化机制。内置的序列化器,如 DataContractSerializer,将能够处理这种情况。你真的需要完全从头开始吗?
  • 其实我从数据库加载加载需要一个数据表行。因此,我坚持使用 DB 的存储过程。 [Serializable] [GeneratedCode("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")] [XmlSchemaProvider("GetTypedTableSchema")] public class Order_ViewDataTable : DataTable, IRecordSource, IEnumerable { } public class Order_ViewRow : DataRow { int Type ; }

标签: c# .net design-patterns architecture load


【解决方案1】:

最简单的方法是使用.Net的内置二进制序列化器

 IFormatter formatter = new BinaryFormatter();
 Stream stream = new FileStream(filename, FileMode.Create, FileAccess.Write,     FileShare.None);
 formatter.Serialize(stream, obj);

并将此代码放入某种 OrderFactory 中

class OrderFactory
{
   public static Order Load(string filename) {...}
   public static void Save(string filename, Order order) {...}
}

【讨论】:

  • 您也可以写出完全限定的类型名称,然后使用 GetType(stringfullyQualifiedName) 通过反射加载类型。与以往一样,使用这些方法时,在更新现场已有历史数据的系统时必须小心。
  • 为什么要重新发明已经存在的东西?而关于历史数据,你可以实现 ISerializable 并以任何你想要的方式控制序列化过程。
  • 这也假设文件中的对象可以通过序列化创建,而不是尝试使用已经存在的格式。
  • Alex Reitbort - 我是谁? Compact Framework 不支持 ISerializable。
  • @Quibblesome:嗯,这个问题从来没有提到紧凑框架。
【解决方案2】:

如果您不想使用 .NET 的内置序列化程序,则需要某种 factory method。你可以把它放在一个单独的工厂对象中,或者像这样在你的基类中创建一个静态函数:

class Order
{
    public static Order CreateOrder(string filename)
    {
         Stream stream = new FileStream(filename);
         string typeinfo = stream.ReadLine();
         Type t=null;
         if(typeinfo=="LimitOrder")  // this can be improved by using "GetType"
            t=typeof(LimitOrder);
         else if(typeinfo==/* what ever your types are*/
            t= //...
         ConstructorInfo consInfo = t.GetConstructor(new Type[0]);
         Order o= (Order)consInfo.Invoke(new object[0]);
         o.Load(stream);
         stream.Close();
         return o;
    }
}

要实现这个功能,每个 Order 子类都必须有一个带 0 个参数的构造函数和一个带流参数的虚拟 Load 方法。并且文件中的第一行必须是 typeinfo。

【讨论】:

    【解决方案3】:

    既然你有这个要求:

    我有基类和几个基类不知道的派生类。基类唯一知道的是类型枚举,它定义了它是哪个实际类。

    为了实现这一点,您的派生类需要提供某种形式的基类注册。一种方法是在基类中定义一个静态Dictionary<MyTypeEnum,Func<Order>>,并允许子类向基类注册自己,以便为它们的类型动态添加特定的创建函数到基类。这样,在解析文件时,基类只需调用相应的函数即可创建派生类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-28
      • 1970-01-01
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多