需要帮助设计类工厂

时间:2010-10-15 14:44:17

标签: c# oop

我有一些具有共同功能的类 - 我需要将它放入基类中。

// 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);

请咨询解决方案。模板没问题

更新

我更新了代码,并展示了如何对象进行序列化和反序列化

3 个答案:

答案 0 :(得分:2)

public class Base<T>
{
    public static T Create(byte[] data)
    {
        // create instance of T from data
    }
}

public Derived1 : Base<Derived1>
{
}

public Derived2 : Base<Derived2>
{
}

答案 1 :(得分:1)

您的设计很好,您只需添加一个模板(具有类约束)

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>
{
}

答案 2 :(得分:1)

如果你想要的是使用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;
        }       
    }
}