【问题标题】:Need help designing class factory需要帮助设计类工厂
【发布时间】:2010-10-15 14:44:17
【问题描述】:

我有一些具有共同特性的类——我需要将它们放入基类中。

// This class needs to be designed
public class Base
{
    // this function is no good because it returns object, and needs to return derived class
    static object Create(byte[] data)
    {
        MemoryStream ms = new MemoryStream(data);
        BinaryFormatter sf = new BinaryFormatter();

        object result = sf.Deserialize(ms);
        ms.Close();

        return result;
    }

    public virtual byte[] Serialize()
    {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(ms, this);
        byte[] result = ms.ToArray();
        ms.Close();
        return result;
    }

}

// for this class Create() must return Derived1
public Derived1 : Base
{
}

// for this class Create() must return Derived2
public Derived2 : Base
{
}

我需要能够像那样使用派生类工厂

Derived1 d1 = Derived1.Create(data1);

Derived2 d2 = Derived2.Create(data2);

请指教解决方案。模板没问题

更新

我更新了代码并展示了对象是如何序列化和反序列化的

【问题讨论】:

  • 我认为您需要进一步解释,因为这没有意义。你打算如何在你的基类中创建“正确的”具体类?
  • Nix,我提供了 Create() 的实现
  • 按照您的操作方式,您将需要使用类约束。见下文。

标签: c# oop


【解决方案1】:
public class Base<T>
{
    public static T Create(byte[] data)
    {
        // create instance of T from data
    }
}

public Derived1 : Base<Derived1>
{
}

public Derived2 : Base<Derived2>
{
}

【讨论】:

  • 你可能需要where T : new()
  • @SLaks:可能,但没有更多细节就无法确定。
  • @chiccodoro:不一定。许多工厂使用反射来使用私有和/或非默认构造函数等来做他们的事情。我确信可能需要某种通用约束,它很可能是new(),但这并不确定问题中给出的信息。
  • @chiccodoro:你去... OP已经编辑了问题,他们正在使用BinaryFormatter反序列化,所以不需要new()约束。
  • 您可能还希望 Base 从非泛型 Base 继承,否则您将遇到多态性问题。
【解决方案2】:

你的设计很好,你只需要添加一个模板(带类约束)

public class Base<T> where T: class
{
  public   static T Create(byte[] data)
  {
    MemoryStream ms = new MemoryStream(data);
    BinaryFormatter sf = new BinaryFormatter();

    T result = sf.Deserialize(ms) as T;
    ms.Close();

    return result;
  }
}

public Derived1 : Base<Derived1>
{
}

public Derived2 : Base<Derived2>
{
}

【讨论】:

    【解决方案3】:

    如果您想要使用 dot Net Serialization 创建一个持久对象,您可以使用以下代码来实现相同的结果。请注意,CSSerialize 定义了使用 BinaryFormatter 和 SoapFormatter 序列化对象的两种方法:

    namespace TheCompany.Common
    {
        public interface IGenericFormatter
        {
            T Deserialize<T>(Stream serializationStream);
            void Serialize<T>(Stream serializationStream, T graph);
        }
        public class GenericFormatter<F> : IGenericFormatter where F : IFormatter, new()
        {
            private IFormatter _Formatter = new F();
            public T Deserialize<T>(Stream serializationStream) { return (T)_Formatter.Deserialize(serializationStream); }
            public void Serialize<T>(Stream serializationStream, T graphObject) { _Formatter.Serialize(serializationStream, graphObject); }
        }
        public class GenericBinaryFormatter : GenericFormatter<BinaryFormatter> { }
        public class GenericSoapFormatter : GenericFormatter<SoapFormatter> { }
    
        public static partial class CSSerialize
        {
            public static T Clone<T>(T source)
            {   
                Debug.Assert(typeof(T).IsSerializable);
                if (!typeof(T).IsSerializable) { throw new SerializationException(ExceptionMessages.ObjectNoSerializable); }
    
                T result;
                IGenericFormatter formatter = new GenericBinaryFormatter();            
                using(MemoryStream stream = new MemoryStream())
                {                
                    formatter.Serialize(stream, source);
                    stream.Seek(0, SeekOrigin.Begin);
                    result = formatter.Deserialize<T>(stream);
                }
                return result;
            }
            public static T CloneXml<T>(T source)
            {
                T result;
                DataContractSerializer serializer = new DataContractSerializer(typeof(T));
                using (MemoryStream memory = new MemoryStream())
                {
                    serializer.WriteObject(memory, source);
                    memory.Position = 0;
                    result = (T)serializer.ReadObject(memory);             
                }
                return result;
            }       
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-19
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      相关资源
      最近更新 更多