调用实现相同接口且派生自同一 Base 的不同类的构造函数
本文关键字:Base 构造函数 同类 派生 实现 接口 调用 | 更新日期: 2023-09-27 18:32:47
我想知道是否有一种方法可以让 ManagerClass 调用共享相同接口并从同一基类继承的不同类的构造函数。我不能调用特定的派生类构造函数本身,因为用户可以选择要在运行时创建的对象,因此直到运行时我才知道要创建哪些派生对象。
例如:
public class managerClass : ISomeInterface
{
public BaseClass apply(someDataType) //(Notice return type is BaseClass)
{
运行派生类的构造函数或创建本质上新的派生对象,将一些数据类型传递到构造函数中
}
}
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 继承,但是如果这以某种方式有助于让我做我想做的事情,我不反对进行此更改。
你可以
看看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
你的问题是什么?当然你可以说:
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;
}
如果您希望开发人员只需创建类,并且您的经理将自动能够创建该类的实例,请使用 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);
}