仅供参考:详细的序言是为了帮助解释我使用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. 附:我对编程比较陌生,所以我很乐意听取开发人员如何设计这个组件(特别是如果我走错了路)。
答案 0 :(得分:0)
我意识到你的代码只是样本,但我发现了这一点......
if (supports[typeof(Entity1).Name]) { bindHandlers<Entity1Reader, Entity1>(Entities1, CamaDbType); }
if (supports[typeof(Entity2).Name]) { bindHandlers<Entity1Reader, Entity1>(Entities1, CamaDbType); }
您是否有可能出现简单的复制/粘贴错误?请注意,两个bindHandlers调用都传入了Entities1。