不同返回类型的 C# 策略设计模式

Pyt*_*oob 5 c# strategy-pattern

我尝试应用策略设计模式来解析一些文本内容,其中每个结果在不同的类中表示。

最小的例子。

所以我的界面是这样的:

public interface IParseStrategy
{
    object Parse(string filePath);
}
Run Code Online (Sandbox Code Playgroud)

实现算法的类:

class ParseA : IParseStrategy
{
    public object Parse(string filePath) => new ConcurrentQueue<ParseAData>();
}

class ParseB : IParseStrategy
{
    public object Parse(string filePath) => new Dictionary<string, ParseBData>();
}
Run Code Online (Sandbox Code Playgroud)

具体的“数据”类:

class ParseAData
{
    public int Id { get; set; }
    public string Name { get; set; }

}

class ParseBData
{
    private byte[] data;

    public byte[] GetData()
    {
        return data;
    }

    public void SetData(byte[] value)
    {
        data = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

定义客户端感兴趣的接口的上下文类:

class Context
{
    private IParseStrategy _strategy;

    private void SetParsingStrategy(IParseStrategy parseStrategy)
    {
        _strategy = parseStrategy;
    }

    public object TryParse(string filePath, TypeToParse typeToParse)
    {
        object parsedContent = new object();

        try
        {
            switch (typeToParse)
            {
                case TypeToParse.A:
                    SetParsingStrategy(new ParseA());
                    parsedContent = _strategy.Parse(filePath);
                    break;
                case TypeToParse.B:
                    SetParsingStrategy(new ParseB());
                    parsedContent = _strategy.Parse(filePath);
                    break;
                    throw new ArgumentOutOfRangeException(nameof(typeToParse), "Uknown type to parse has been provided!");
            }
        }
        catch (Exception)
        {

            throw;
        }

        return parsedContent;
    }

}
Run Code Online (Sandbox Code Playgroud)

客户端可以选择正确算法的枚举

public enum TypeToParse { A, B }
Run Code Online (Sandbox Code Playgroud)

最后是主要方法:

static void Main(string[] args)
{
    var context = new Context();
    ConcurrentQueue<ParseAData> contentOfA = (ConcurrentQueue<ParseAData>)context.TryParse("file1.whatever", TypeToParse.A);
    Dictionary<string, ParseBData>contentOfB = (Dictionary<string, ParseBData>)context.TryParse("file2.whatever", TypeToParse.B);
}
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是客户端必须知道类才能转换返回类型object

如何将其重写为更通用的方式,以便编译器使用var关键字自动推断类型,因此调用将如下所示:

        var contentOfA = context.TryParse("file1.whatever", TypeToParse.A);
        var contentOfB = context.TryParse("file2.whatever", TypeToParse.B);
Run Code Online (Sandbox Code Playgroud)

推断出黄色标记的类型:

在此处输入图片说明

小智 1

简单的答案是你不能,解决这个问题:

所以,我的问题是客户端必须知道类才能转换返回类型对象。

无论给出什么答案,用户都需要知道将要返回的对象的类型,直到运行时或者上下文类的用户只有在了解该类的内部实现的情况下才可能知道这一点Context

然而,这种类型的代码不适合,因为您的接口保证的唯一事情是返回一个对象。

如果 的用户Context必须将选项传递给TypeToParse上下文类的函数,则最好有 2 个返回正确类型的函数,例如

class Context
{
    public ParseAData ParseAsA(string filePath)
    {
        ...
    }

    public ParseBData ParseAsB(string filePath)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)