Переопределить методы в параллельных иерархиях классов - PullRequest
0 голосов
/ 11 января 2019

Какие есть варианты решения проблем с параллельными иерархиями наследования ниже? Я хотел бы сохранить классы сериализатора без сохранения состояния.

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 {...});
    }

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Пару лет назад у меня была возможность немного узнать о функциональном программировании с использованием Haskell, и большинство концепций FP показалось мне действительно интуитивным. Так как я не был доволен предложениями для моих вопросов, у меня была действительно хорошая идея спросить себя: как я буду делать это в Haskell? Итак, ниже мое решение, вдохновленное мышлением с точки зрения FP. По сути, я отказываюсь от одной из иерархий наследования (с классами сериализатора) и вместо этого использую статические методы. Функциональное программирование делает меня лучшим программистом ООП ... правдивая история!

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

    }
}
0 голосов
/ 11 января 2019

Расширение первого предложения в комментариях:

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
        {

        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...