【问题标题】:Override methods in parallel class hierarchies覆盖并行类层次结构中的方法
【发布时间】:2019-06-05 21:23:19
【问题描述】:

我有哪些选项可以解决以下并行继承层次结构的问题?我想让 Serializer 类保持无状态。

public abstract class BaseSerializerOptions
{
    public Boolean SortComponents { get; set; }
}

public class TextSerializerOptions : BaseSerializerOptions
{
    public Int32 TrimStrings { get; set; }
}

public class BinarySerializerOptions : BaseSerializerOptions
{
    public Boolean SkipNulls { get; set; }
}

public abstract class BaseSerializer
{
    public abstract void Serialize(Object obj, Stream s, BaseSerializerOptions opt);
}

public class TextSerializer : BaseSerializer
{
    public override void Serialize(Object obj, Stream s, TextSerializerOptions opt)
    {
    }
}

public class BinarySerializer : BaseSerializer
{
    public override void Serialize(Object obj, Stream s, BinarySerializerOptions opt)
    {
    }
}

我希望能够编写这样的方法:

    static void Test(BaseSerializer s, BaseSerializerOptions o)
    {
        var obj = new MyObject { ... };
        using (var f = File.OpenWrite("..."))
        {
            s.Serialize(obj, f, o);
        }
        // do more things here to check the serializer result; 
        // the serializers might return some kind of operation status, which I want to check
    }

    static void TestSerializers()
    {
        Test(new TextSerializer(), new TextSerializerOptions {...});
        Test(new BinarySerializer(), new BinarySerializerOptions {...});
    }

【问题讨论】:

  • class BaseSerializer<T> where T : BaseSerializerOptions { public abstract void Serialize(Object obj, Stream s, T opt); } 怎么样?
  • 我认为您不需要BaseSerializer,因为目前还不清楚您将如何将它与通用选项一起使用。我个人会: 1. 完全删除BaseSerializer 并为特定任务使用特定的序列化程序。 2. 将options移动到特定序列化器的构造函数中,将BaseSerializer替换为ISerializerSerializer(object obj, Stream s)方法。
  • 两个建议看起来都不错,请发布完整的答案,让作者更清楚
  • @opewix,第二个建议不是我想要的;我想保持Serializer 类无状态;我不想将选项保留为序列化程序中的状态。
  • 第一个建议也不是很有帮助;我不能将BaseSerializer<T> 类用作普通的抽象基类,因为它依赖于具体的选项类。

标签: c# oop design-patterns


【解决方案1】:

几年前,我有机会使用 Haskell 学习了一点函数式编程,大多数 FP 概念对我来说似乎都很直观。因为我对我的问题的建议不满意,所以我有一个很好的主意问自己:我将如何在 Haskell 中做到这一点?所以,下面是我的解决方案,灵感来自 FP 的观点。基本上我放弃了继承层次结构之一(带有序列化程序类的继承层次结构),而是使用静态方法。函数式编程让我成为更好的 OOP 程序员……真实的故事!

public abstract class BaseSerializerOptions
{
    Boolean SortComponents { get; set; }
}

public class TextSerializerOptions : BaseSerializerOptions
{
    public Boolean TrimStrings { get; set; }
}

public class BinarySerializerOptions : BaseSerializerOptions
{
    public Boolean SkipNulls { get; set; }
}

public class SerializerResult
{

}

public static class Serializer
{
    public static SerializerResult Write(Object obj, Stream s, BaseSerializerOptions opt)
    {
        switch (opt)
        {
            case TextSerializerOptions o: return WriteText(obj, s, o);
            case BinarySerializerOptions o: return WriteBinary(obj, s, o);
        }
        throw new Exception();
    }

    public static SerializerResult WriteText(Object obj, Stream s, TextSerializerOptions opt)
    {
        return null;
    }

    public static SerializerResult WriteBinary(Object obj, Stream s, BinarySerializerOptions opt)
    {
        return null;
    }
}

class Program
{
    static void Test(BaseSerializerOptions o)
    {
        var obj = new Object();

        using (var fs = File.Open("...", FileMode.Create))
        {
            var r1 = Serializer.Write(obj, fs, o);
            CheckSerializerResults(r1);
        }
    }

    static void TestSerializers()
    {
        Test(new TextSerializerOptions { TrimStrings = true });
        Test(new BinarySerializerOptions { SkipNulls = false });
    }

    static void CheckSerializerResults(SerializerResult r)
    {

    }
}

【讨论】:

    【解决方案2】:

    扩展 cmets 中的第一个建议:

    public abstract class BaseSerializerOptions
    {
        public Boolean SortComponents { get; set; }
    }
    
    public class TextSerializerOptions : BaseSerializerOptions
    {
        public Int32 TrimStrings { get; set; }
    }
    
    public class BinarySerializerOptions : BaseSerializerOptions
    {
        public Boolean SkipNulls { get; set; }
    }
    
    public abstract class BaseSerializer<T> where T : BaseSerializerOptions
    {
        public abstract void Serialize(Object obj, Stream s, T opt);
    }
    
    public class TextSerializer : BaseSerializer<TextSerializerOptions>
    {
        public override void Serialize(Object obj, Stream s, TextSerializerOptions opt)
        {
        }
    }
    
    public class BinarySerializer : BaseSerializer<BinarySerializerOptions>
    {
        public override void Serialize(Object obj, Stream s, BinarySerializerOptions opt)
        {
        }
    }
    

    特定语法用法的更新:

    public class TextSerializer : BaseSerializer
    {
        public void Serialize(Object obj, Stream s, TextSerializerOptions opt)
        {
            this.Serialize(obj, s, opt);
        }
    
        public override void Serialize(object obj, Stream s, BaseSerializerOptions opt)
        {
            if (opt is TextSerializerOptions options)
            {
    
            }
            else
            {
    
            }
        }
    }
    
    public class BinarySerializer : BaseSerializer
    {
        public void Serialize(Object obj, Stream s, BinarySerializerOptions opt)
        {
            this.Serialize(obj, s, opt);
        }
    
        public override void Serialize(object obj, Stream s, BaseSerializerOptions opt)
        {
            if (opt is BinarySerializerOptions options)
            {
    
            }
            else
            {
    
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-28
      • 1970-01-01
      相关资源
      最近更新 更多