C# 调用实现同一接口且派生自同一基的不同类的构造函数?

C# 调用实现同一接口且派生自同一基的不同类的构造函数?,c#,class,inheritance,design-patterns,interface,C#,Class,Inheritance,Design Patterns,Interface,我想知道是否有一种方法可以让ManagerClass调用共享同一接口并从同一基类继承的不同类的构造函数。我不能自己调用特定的派生类构造函数,因为用户可以选择在运行时创建哪些对象,因此直到运行时我才知道要创建哪些派生对象 例如: public class managerClass : ISomeInterface { public BaseClass apply(someDataType) //(Notice return type is BaseClass) { 运行派生类的构造

我想知道是否有一种方法可以让ManagerClass调用共享同一接口并从同一基类继承的不同类的构造函数。我不能自己调用特定的派生类构造函数,因为用户可以选择在运行时创建哪些对象,因此直到运行时我才知道要创建哪些派生对象

例如:

public class managerClass : ISomeInterface
{
   public BaseClass apply(someDataType) //(Notice return type is BaseClass) 
   {
运行派生类的构造函数或创建新的派生对象,将someDataType传递到构造函数中


当前managerClass没有从同一基类继承,但是如果这有助于我做我想做的事情,我并不反对进行此更改。

您可以查看
激活器
类:

Type type = typeof(derivedClass2);
ISomeInterface instance = (ISomeInterface)Activator.Create(type);
还有一些重载,比如传递类名而不是类型

更多信息:


否则,您应该在这里查看工厂设计模式

您的问题是什么?当然你可以说:

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;
}

如果您希望开发人员只需创建该类,并且您的经理将能够自动创建该类的实例,请使用反射来收集要呈现给用户的选项列表,并在请求时使用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]);
}
然后在枚举期间检索这些,并将其与选项一起存储

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
                     }
                );
            }
    }
}

您想让manager类根据用户输入创建不同具体类的实例吗?是的,可能吗?查找抽象工厂模式,看看这是否适合您的用例。旁注:不要通过添加manager来污染层次结构。创建一个独立的工厂要干净得多。管理器可能没有实现基类的方法,因此它不应从基类继承。我不想这样做,因为这样设计是不可扩展的,如果开发人员要创建另一个派生类,他们还需要添加此“if条件”。当前ManagerClass存储所有实现ISomeInterface并调用其doSmthg方法的对象,因此,如果开发人员要创建另一个derivedClass,他们只需实现该方法并从基类继承。您的条件是什么?用户是否正在传递要创建的实现的名称?@user1084113您应该编辑您的问题,以包含存在许多派生类的信息,稍后可能需要添加更多。您还应该写一些关于如何确定在每个特定情况下使用哪个派生类的内容。在处理
derivedClass
derivedClass2
时,我可能误解了你的问题。
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);
}