我想知道是否有办法让一个ManagerClass调用不同类的构造函数,这些构造函数共享相同的接口并从相同的基类继承。我无法调用特定的派生类构造函数本身,因为用户可以选择在运行时创建哪些对象,因此我不知道在运行时要创建哪些派生对象。
例如:
public class managerClass : ISomeInterface
{
public BaseClass apply(someDataType) //(Notice return type is BaseClass)
{
运行derivedClasses的构造函数或创建基本上新的派生对象,将someDataType传递给构造函数
}
}
public class derivedClass : BaseClass, ISomeInterface
{
public void doSmthg(){manipulate data and store}
}
public class derivedClass2 : BaseClass, ISomeInterface
{
public void doSmthg(){manipulate data in another way and store}
}
目前managerClass不会从同一个BaseClass继承,但是如果这有助于我做我想做的事情,我并不反对做出这样的改变。
答案 0 :(得分:0)
您可以查看Activator
课程:
Type type = typeof(derivedClass2);
ISomeInterface instance = (ISomeInterface)Activator.Create(type);
还有一些重载,比如传递类名而不是类型。
更多信息:http://msdn.microsoft.com/en-us/library/system.activator.aspx
否则,您应该Factory Design Pattern
http://msdn.microsoft.com/en-us/library/ee817667.aspx
答案 1 :(得分:0)
你有什么问题?当然你可以说:
public BaseClass Apply(SomeDataType someDataType)
{
BaseClass instance;
if (/* your condition */)
{
var dc = new DerivedClass();
// do stuff to/with dc
instance = dc;
}
else
{
var dc2 = new DerivedClass2();
// do stuff to/with dc2
instance = dc2;
}
// do common stuff to/with instance
return instance;
}
答案 2 :(得分:0)
如果您希望开发人员只需要创建类,您的经理将自动创建它的实例,使用Reflection来收集要呈现给用户的选项列表,并使用Activator创建请求的实例。
Dictionary<string, Type> DerivedOfferings{get;set;}
... //somewhere in the setup of your manager.
foreach (Type t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IEmtRequestProcessor)))))
{
DerivedOfferings.Add(t.Name, t);
}
//provide list of options to users.
IList<string> GetOfferingOptions(){
return DerivedOfferings.Keys.ToList();
}
...
public BaseClass GetOffering(string name){
return (BaseClass)Activator.CreateInstance(DerivedOfferings[type]);
}
如果需要执行某些逻辑来决定要创建哪个派生产品,您可以为开发人员提供一个属性来装饰他们的类,这些属性将保存信息以执行逻辑。
public sealed class CreatureAttribute:Attribute
{
public int NumberOfLegs{get;set;}
public Color HairColor{get;set;}
public int NumberOfWings{get;set;}
public bool BreathsFire{get;set;}
}
[CreatureAttribute(NumberOfLegs=6, HairColor = Color.Magenta, NumberOfWings=0, BreathsFire=True)]
public class PurpleDragon: ICreature
{
...
}
然后在枚举期间检索这些并使用选项存储它们。
List<CreatureCriteria> CreatureOptions{get;set;}
EnumerateOptions()
{
foreach (Type t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ICreature)))))
{
foreach (CreatureAttribute creatureAttribute in
t.GetCustomAttributes(typeof (CreatureAttribute), false)
.Cast<CreatureAttribute>()
{
CreatureOptions.Add(
new CreatureCriteria{
Legs = creatureAttribute.NumberOfLegs,
HairColor = creatureAttribute.HairColor,
...
ConcreteType = t
}
);
}
}
}
根据用户提供的标准进行评估..
ICreature CreateCreature(CreatureCriteria criteria){
CreatureCriteria bestMatch = CreatureOptions.FindBestMatch(criteria);
// perform logic comparing provided criteria against CreatureOptions to find best match.
return (ICreature)Activator.CreateInstance(bestMatch.ConcreteType);
}