首先,我一直在努力争取这个问题的标题,所以如果您认为自己有更好的想法,请编辑它。
这似乎是我一次又一次遇到的问题,并最终做了一些臭臭来规避。一般形式似乎是我有一个非泛型类,用于获取某个实例(即工厂),但需要做出关于实例应该具有什么类型的决定。我认为下面的示例说明了我的目标,但您注意到它没有编译,因为在FooBarFactory
我无法使用AbstractThing
T
在该上下文中不允许使用摘要。那么我怎样才能让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
}
答案 0 :(得分:1)
泛型的主要目的是提供编译时类型的安全性。让#39;让FooBarFactory在运行时确定if (number1 > number2)
{
if (number1 > number3)
largest = number1;
else
largest = number3;
}
else
{
if (number2 > number3)
largest = number2;
else
largest = number3;
}
if (number1 < number2)
{
if (number1 < number3)
smallest = number1;
else
smallest = number3;
}
else
{
if (number2 < number3)
smallest = number2;
else
smallest = number3;
}
应该用于Generator<T>
&#34;的类型是没有意义的。
我的目的是强制工厂返回AbstractThing。
这是由返回类型为T
的工厂方法强制执行的。
你会在这里推荐什么?工厂应该只为AbstractThing的每个子类型设置一个方法吗?
GetThing方法,即工厂方法,应该根据您的某些逻辑返回AbstractThing
,即非通用工厂本身决定是返回Foo还是Bar对象。泛型并不适用于此。
或者也许应该在工厂中没有Generator的实例,而是在每个案例块中新建相应的Generator?
您不一定需要任何生成器类。如果需要,您可以实现决定是否应在工厂方法中直接创建AbstractThing
或Foo
的逻辑。工厂将N个参数作为输入,并根据工厂中抽象出来的一些逻辑返回Bar
类型的具体实现。
希望这是有道理的。