C# 字典trygetvalue null private Dictionary events=new Dictionary(); 内部包GetEventList(),其中T:class { 类型=类型(T); b袋; if(events.TryGetValue(类型,输出b)) { 返回b作为包; } 否则{ b=新袋()作为袋; 事件[类型]=b; 返回b作为包; } } 内部无效添加事件(T ev),其中T:类别、事件 { 类型=类型(T); b袋; if(events.TryGetValue(类型,输出b)) { b、 添加(ev);//
可能的罪魁祸首是这一行:C# 字典trygetvalue null private Dictionary events=new Dictionary(); 内部包GetEventList(),其中T:class { 类型=类型(T); b袋; if(events.TryGetValue(类型,输出b)) { 返回b作为包; } 否则{ b=新袋()作为袋; 事件[类型]=b; 返回b作为包; } } 内部无效添加事件(T ev),其中T:类别、事件 { 类型=类型(T); b袋; if(events.TryGetValue(类型,输出b)) { b、 添加(ev);//,c#,dictionary,nullreferenceexception,C#,Dictionary,Nullreferenceexception,可能的罪魁祸首是这一行: private Dictionary<Type, Bag<Event>> events = new Dictionary<Type, Bag<Event>>(); internal Bag<T> GetEventList<T>() where T:class { Type type = typeof(T); Bag<Event> b; if (events
private Dictionary<Type, Bag<Event>> events = new Dictionary<Type, Bag<Event>>();
internal Bag<T> GetEventList<T>() where T:class
{
Type type = typeof(T);
Bag<Event> b;
if (events.TryGetValue(type, out b))
{
return b as Bag<T>;
}
else {
b = new Bag<T>() as Bag<Event>;
events[type] = b;
return b as Bag<T>;
}
}
internal void AddEvent<T>(T ev) where T:class,Event
{
Type type = typeof(T);
Bag<Event> b;
if (events.TryGetValue(type, out b))
{
b.Add(ev); // <= NullReferenceException, b is null
}
else {
b = new Bag<T>() as Bag<Event>;
events.Add(type, b);
b.Add(ev);
}
}
b=新行李(),作为行李;
as
转换可能失败,这将null
分配给b
我的猜测是,您正在使用Event
的子类作为T
的类型,并且由于Bag
在类型参数上是不协变的(我假设它是一个类,所以它不可能是),强制转换失败,最终导致b
为null
更新:根据下面的评论,问题确实是
的演员阵容。要解决问题,只需创建一个新包()
,无需演员阵容。可能的罪魁祸首是这一行:
private Dictionary<Type, Bag<Event>> events = new Dictionary<Type, Bag<Event>>();
internal Bag<T> GetEventList<T>() where T:class
{
Type type = typeof(T);
Bag<Event> b;
if (events.TryGetValue(type, out b))
{
return b as Bag<T>;
}
else {
b = new Bag<T>() as Bag<Event>;
events[type] = b;
return b as Bag<T>;
}
}
internal void AddEvent<T>(T ev) where T:class,Event
{
Type type = typeof(T);
Bag<Event> b;
if (events.TryGetValue(type, out b))
{
b.Add(ev); // <= NullReferenceException, b is null
}
else {
b = new Bag<T>() as Bag<Event>;
events.Add(type, b);
b.Add(ev);
}
}
b=新行李(),作为行李;
as
转换可能失败,这将null
分配给b
我的猜测是,您正在使用Event
的子类作为T
的类型,并且由于Bag
在类型参数上是不协变的(我假设它是一个类,所以它不可能是),强制转换失败,最终导致b
为null
更新:根据下面的评论,问题确实是as
强制转换。要解决问题,只需创建一个新包()
,无需强制转换。某个空值与密钥类型关联
在抛出NullReferenceException
之前,在调试器中逐步检查代码并检查字典的状态。在某个地方,null与键类型相关联
在抛出NullReferenceException
之前,在调试器中逐步检查代码,并检查字典的状态。NullReferenceException
在Bag
无法强制转换到Bag
时抛出
如果您将签名更改为内部无效添加事件(事件ev),其中T:class
异常将解除NullReferenceException
在Bag
无法转换为Bag
时抛出
如果您将签名更改为internal void AddEvent(Event ev),其中T:class
异常将被解除,因为您的Bag b;
在字典中为空?您确定b=new Bag()as Bag;
不是null
?您能告诉我们您正在调用的代码,以及围绕事件的任何类型层次结构吗?因为您的Bag b;
在字典中是null吗?您确定b=new Bag()因为Bag;
不是null
?您能告诉我们您正在调用的代码,以及围绕事件的任何类型层次结构吗?
?它不会在最后一个b.Add(ev)中引发另一个NullReferenceException吗;如果是这样的话?@LimoWanKenobi我只能推测,因为我们还没有看到调用代码,但我猜最初的调用使用Event
作为泛型参数,但随后的调用没有。另一种可能是GetEventList()
调用首先发生,但在字典中找不到该类型,因此该方法中的as
强制转换将导致null,导致下一次为给定类型调用add时出现null ref。无论实际顺序如何,很可能是问题出在as
强制转换。在第一个方法中,GetEventList
,他还使用as
操作符,他还添加到字典中
那里!他只是使用索引器的setter来执行。而且该方法甚至不将其t
约束为事件
。Alejandro,永远不要使用as
操作符,除非您同意结果可能是null
。如果您不准备处理null
,请使用“硬”强制转换。在您的代码中,T
和Event
之间有什么关系?-好的,让我们看看。在我的代码中,“Event”是一个接口,而T实现了该接口。-我添加了一些断点,在AddEvent()之前没有调用GetEventList()-我将删除“as”强制转换,看看会发生什么。谢谢。@dlev调用代码:(CellsChangedEvent实现事件)world.SystemManager.AddEvent(新CellsChangedEvent(实体));
它不会在最后一个b.Add(ev)中引发另一个NullReferenceException吗;如果是这样的话?@LimoWanKenobi我只能推测,因为我们还没有看到调用代码,但我猜最初的调用使用Event
作为泛型参数,但随后的调用没有。另一种可能是GetEventList()
调用首先发生,但在字典中找不到该类型,因此该方法中的as
强制转换将导致null,导致下一次为给定类型调用add时出现null ref。无论实际顺序如何,很可能是问题出在as
强制转换。在第一个方法中,GetEventList
,他还使用as
操作符,他还添加到字典中
那里!他只是使用索引器的setter来执行。而且该方法甚至不将其t
约束为事件
。Alejandro,永远不要使用as
操作符,除非您同意结果可能是null
。如果您不准备处理null
,请使用“硬”强制转换。在您的代码中,T
和Event
之间有什么关系?-好的,让我看看。在我的代码中,“Event”是一个接口,而T实现了该接口。-我补充道