繁体   English   中英

在非泛型类中创建泛型

[英]Creating Generics in Non-Generic Class

首先,我很难为这个问题加上标题,因此,如果您认为自己有更好的主意,请对其进行编辑。

这似乎是我不时遇到的问题,并且最终做了臭味回避。 一般的形式似乎是我有一个非泛型类,用于获取某事物的实例(即Factory),但是需要确定该实例应具有的类型。 我认为下面的示例说明了我要执行的操作,但是您会注意到它无法编译,因为在FooBarFactory我不能将AbstractThing用于T因为在该上下文中不允许使用AbstractThing 因此,如何让FooBarFactory在运行时确定Generator<T>应该用于T的类型?

public class FooBarFactory
{
    private Generator<AbstractThing> _generator;

    public AbstractThing GetThing(string data, ThingType type)
    {
        switch (type)
        {
            case ThingType.Foo:
                _generator = new FooGenerator();
                break;

            case ThingType.Bar:
                _generator = new BarGenerator();
                break;

            case ThingType.None:
                return null;

            default:
                throw new ArgumentOutOfRangeException(nameof(type), type, null);
        }

        return _generator.Generate(data);
    }
}

public abstract class Generator<T> where T : AbstractThing, new()
{
    protected T GeneratedThing = new T();

    protected abstract void MapDataToThing(string data);

    public T Generate(string data)
    {
        MapDataToThing(data);
        return GeneratedThing;
    }
}

public class FooGenerator : Generator<Foo>
{
    protected override void MapDataToThing(string data)
    {
        GeneratedThing.AbstractProp = ParseAbstract(data);
        GeneratedThing.FooProp = ParseFoo(data);
    }

    private static string ParseAbstract(string data)
    {
        throw new NotImplementedException();
    }

    private static string ParseFoo(string data)
    {
        throw new NotImplementedException();
    }
}

public class BarGenerator : Generator<Bar>
{
    protected override void MapDataToThing(string data)
    {
        GeneratedThing.AbstractProp = "Base property in Bar";
        GeneratedThing.BarProp = data.Substring(4, 3);
    }
}

public abstract class AbstractThing
{
    public string AbstractProp { get; set; }
}

public class Foo : AbstractThing
{
    public string FooProp { get; set; }
}

public class Bar : AbstractThing
{
    public string BarProp { get; set; }
}

public enum ThingType
{
    None = 0,
    Foo = 1,
    Bar = 2
}

泛型的主要目的是提供编译时类型的安全性。 “让FooBarFactory在运行时确定Generator<T>应该为T使用哪种类型”是没有意义的。

我的意图是强制工厂返回AbstractThing。

这由具有返回类型AbstractThing的factory方法实施。

您会在这里推荐什么? 工厂是否应该为AbstractThing的每个子类型简单地使用一种方法?

GetThing方法(即工厂方法)应根据您的某些逻辑简单地返回AbstractThing ,即由非泛型工厂本身决定要返回Foo还是Bar对象。 泛型在这里并不真正适用。

也许在工厂中应该没有Generator的实例,而是在每个case块中更新适当的Generator?

您不一定需要任何生成器类。 如果需要,您可以实现决定是否应在工厂方法本身中直接创建FooBar的逻辑。 工厂将N个参数用作输入,并根据工厂中提取的某些逻辑返回AbstractThing类型的具体实现。

希望有道理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM