使用类型来实例化使用受限制的仿制药的派生类



我正在使用一个通用的工厂类,其中通用零件是正在使用的派生类。正常用法很明显:BaseClass<DerivedA> C = new BaseClass<DerivedA>().现在尽管我试图将财产注入放入我使用这些类的班级中。为此,我试图将类型作为参数(以便我可以使用派生的类别(。

现在,尽管我寻找例子并在自己身边尝试,但我有些亏损。我现在想知道:根本可以使用这种结构吗?如果是这样,我该如何实例化和使用,并且存在?

存在?

用法:

public class MyMainClass
{
    object _ClassInstance; // BaseClass<DerivedA> or BaseClass<DerivedB>
    public MyyMainClass(Type typeIWant)
    {
          .....
    }
}
....
MyMainClass a = new MyMainClass(typeof(DerivedA));
MyMainClass b = new MyMainClass(typeof(DerivedB));

通用类:

public abstract class BaseClass<T> where T: BaseClass<T>, new()
{
...
    public bool Exists(int a) {...}
}

派生类:

public class DerivedA :BaseClass<DerivedA>
{
...
}
public class DerivedB :BaseClass<DerivedB>
{
...
   public bool ExistsB(string a) {...}
}

您可以创建一个通过此操作的任何类型的实例:

_ClassInstance = Activator.CreateInstance(typeIWant)

不建议这样做,因为您将永远检查其类型并在要使用一种基本方法之一时施放它。如果您能够更改主类以进行类型参数,则应该像这样:

public class MyMainClass<T> where T: BaseClass<T>, new()
{
    T _ClassInstance; // BaseClass<DerivedA> or BaseClass<DerivedB>
    public MyMainClass()
    {
        _ClassInstance = new T();
    }
}

这将允许您使用Baseclass上定义的任何方法。鉴于您要使用"不存在",这不是,您仍然需要在运行时检查其类型并施放它。我会推荐这样的东西:

if (_ClassInstance is DerivedB derivedB)
    derivedB.ExistsB("...");

如果您确实需要编译时间检查,我建议您的课程需要更改。您无法仅访问派生类上定义的方法或属性,仅参考基础类。

这是您想要的吗?

Object instance1 = Activator.CreateInstance<Object>();
Object instance2 = Activator.CreateInstance(typeof(object));

我建议您使用getType使用类型名称。如果您升级继承(从派生b等继承了另一个类(,如果您使用getType,则可以确保仅适用于派生类型的实例调用此方法。

MyMainClass b = new MyMainClass(typeof(DerivedB));
if(b.GetType() == typeof(DerivedB)) 
b.ExistsB(...);

这是抽象类的主要问题 - 您共享接口和实现。但是就您而言,您强烈依赖不同的界面。要简化问题,只需查看您实际想要的东西:

public interface IExistable<in TValue>
{
    bool Exists(TValue value);
}
public interface IDerivedA : IExistable<int>
{
}
public interface IDerivedB : IExistable<int>, IExistable<string>
{
}

您可以看到,您用两个接口使IDERIVEDB过度复杂化,也就是说,您的主级在某些情况下取决于IDERIVEDB。扩展接口还不错,您只是使用它错误。因此,您必须做的是为主级定义接口:

public interface IMainClass
{
    //some methods here
}

创建两个实现:

public class ConcreteMainClass : CommonMainClass //you can derive from common, delegate to inner instance or implement interface from scratch - you decide depending on situation
{
    private readonly IDerivedB _instance;
    public ConcreteMainClass(IDerivedB instance) : base(instance)
    {
        _instance = instance;
    }
    //you can override some logic here depending on IExistable<string> from IDerivedB
}
public class CommonMainClass : IMainClass
{
    private readonly IExistable<int> _instance;
    public CommonMainClass(IExistable<int> instance)
    {
        _instance = instance;
    }
    //this is where you don't depend on IExistable<string>
}

这样,您可以编写更多清晰的代码:

IMainClass a = new CommonMainClass(new DerivedA());
IMainClass b = new ConcreteMainClass(new DerivedB());

ps :最好将依赖项传递到班级生命周期的上层,而不是在内部激活它,因此您可以使用工厂来为您甚至依赖注入创建它们。

ps2 :在抽象类之前使用接口。接口/构造函数/方法描述了您的整体依赖性。另一方面,抽象类只是一种重复使用实现的方式 - 它们并不是要定义接口或与课程的工作方式,您可以将整个身体私有/受保护而无需共享任何内容。

最新更新