C#激活器.CreateInstance通用实例丢失
本文关键字:实例 激活 CreateInstance | 更新日期: 2023-09-27 18:28:54
FYI:详细的序言有助于解释我使用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();
}
为"Handler"类定义一个接口,即这些类实现上面列出的查询操作。
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*/}
}
这允许开发人员创建一个单独的类来处理DbTypeM
的EntityN
查询操作。现在,创建一个包含读取器对象并将处理程序方法绑定到读取器委托的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
的构造函数中看到的那样,按照现在编写代码的方式,即使创建了EntityNReader
的实例r
并且(验证为)不是null,我也会得到NullReferenceException
。
但是,如果我实例化EntitiesN
,它在Database
中声明,而不是在bindHandlers
中声明,那么代码就会编译,一切都正常。我不这么做的原因是(随后)我想在Database
类实例化时,在bindHandlers
内部有条件地创建读取器/处理程序。
这里发生了什么?如有必要,链接到实际代码。附言:我对编程还比较陌生,所以我很乐意听取经验丰富的开发人员如何设计这个组件(尤其是如果我走错了路)。
我知道你的代码只是样本,但我一开始就发现了。。。
if (supports[typeof(Entity1).Name]) { bindHandlers<Entity1Reader, Entity1>(Entities1, CamaDbType); }
if (supports[typeof(Entity2).Name]) { bindHandlers<Entity1Reader, Entity1>(Entities1, CamaDbType); }
你可能有一个简单的复制/粘贴错误吗?请注意,两个bindHandlers调用都传入了Entities1。