C#Activator.CreateInstance泛型实例迷路了

时间:2014-11-03 03:37:46

标签: c# orm factory late-binding activator

仅供参考:详细的序言是为了帮助解释我使用Activator.CreateInstance的原因。我有许多实体(对应于数据库列信息的对象)是"包含"在多个数据库中,每个数据库都有不同的表/列设置。所以我能够从每个数据库中检索一个实体,但每个数据库检索它的方式都不同。数据库类型直到运行时才知道,并且可能在整个执行过程中变化我创建了以下设置:

首先定义每个实体应该支持的查询操作,每个实体读者都应该支持这些操作。

public abstract class Operations<T> {
    public delegate T findDelegate(int id);
    public findDelegate find;
}

// there are many of these N=1,2,..., but here is one
// use abstract class since implementation of queries should be done by handlers
public class EntityNReader : Operations<EntityN> {
    public Reader();
}

定义&#34; Handler&#34;的界面类,即这些类实现上面列出的查询操作。

public interface IHandler<T> {
    public string find(int id);
}

// there are many of these N,M=1,2..., but here is one
// use of interface is to force handlers to implement all query types
public class EntityNHandlerForDbTypeM : IHandler<EntityN> {
    public string find(int id) {/*whatever*/}
}

这允许开发人员创建一个类来处理EntityN的{​​{1}}查询操作。现在,创建一个包含reader对象的DbTypeM类,并将处理程序方法绑定到reader委托人。

Database

正如您在public class Database { // there are many of these, but here is one public EntityNReader EntitiesN; public Database(string dbType) { // this is called for each EntityNReader bindHandlers<Reader, TypeN>(MyReader, dbType); // ... // nullreferenceexception EntitiesN.find(0); } // this is a factory that also performs late binding private void bindHandlers<T,K>(T reader, string dbTypeM) where T: Operations<K>, new() { // create instance of EntityNReader r = (T)Activator.CreateInstance(typeof(T)); // r != null // create instance of handler IHandler<K> h = (IHandler<K>)(Activator.CreateInstance( Type.GetType("namespace.to.EntityNHandlerForDbTypeM"), new object[] { this } )); // bind delegates r.find = h.find; } } 构造函数中看到的那样,现在编写代码的方式,即使创建了Database的实例NullReferenceException,我也会获得r并且(经核实无效。

但是,如果我实例化EntityNReader EntitiesN而不是Database中的声明,则代码会编译并且一切正常。我不这样做的原因是(随后)我想在bindHandlers类实例化时有条件地在bindHandlers内创建读者/处理程序。

这里发生了什么? Link to actual code if necessary. 附:我对编程比较陌生,所以我很乐意听取开发人员如何设计这个组件(特别是如果我走错了路)。

1 个答案:

答案 0 :(得分:0)

我意识到你的代码只是样本,但我发现了这一点......

if (supports[typeof(Entity1).Name]) { bindHandlers<Entity1Reader, Entity1>(Entities1, CamaDbType); }
if (supports[typeof(Entity2).Name]) { bindHandlers<Entity1Reader, Entity1>(Entities1, CamaDbType); }

您是否有可能出现简单的复制/粘贴错误?请注意,两个bindHandlers调用都传入了Entities1。