提问人:Totte 提问时间:2/20/2023 最后编辑:Bill Tür stands with UkraineTotte 更新时间:2/20/2023 访问量:1241
取消引用可能为空的引用警告
Dereference of a possibly null reference warning
问:
我有一个名为 .conversationService
当我尝试在对象上调用方法时,我收到警告:
“conversationService”在这里可能为 null。CS8602:取消引用 可能为 null 引用。
问题是,我不认为它在那里可以是空的。我是否遗漏了什么,我怎样才能摆脱这个警告?
这是我的代码:
public string GetNextState(string input)
{
if (conversationService == null)
LoadConversationService();
List<ConversationResponse> responses = conversationService.PredictResponse(new Conversation(input));
return responses.First().Text;
}
public void LoadConversationService()
{
conversationService = new ConversationService();
}
下图显示了带有警告的代码:
我知道我可以把它写成
conversationService!.PredictResponse();
但我认为它引入了不应该需要的混乱。
我尝试检查空引用,然后在收到警告的代码行之前处理它。我希望它能使编译器明白,当取消引用发生时,它不能为空,但它不明白。
答:
0赞
JDChris100
2/20/2023
#1
发生这种情况的原因是,初始化此类的构造函数时,conversationService 为 null。若要避免此问题,可以直接在类的构造函数中创建 conversationService 对象的实例,如下所示:
private ConversationService conversationService = new ConversationService();
public string GetNextState(string input)
{
List<ConversationResponse> responses = conversationService.PredictResponse(new Conversation(input));
return responses.First().Text;
}
此方法将防止发生 null 警告。
你也可以将 conversationResponse 包装在 Getter 中,例如
public string GetNextState(string input)
{
List<ConversationResponse> responses = GetConversationService().PredictResponse(new Conversation(input));
return responses.First().Text;
}
public ConversationService GetConversationService()
{
if(conversationService == null) conversationService = new ConversationService();
return conversationService();
}
或者,可以使用 null 宽恕运算符 (!) 来禁止显示这些警告,就像之前所做的那样。
评论
0赞
Totte
2/21/2023
我没有在我的问题中显示真正的代码。实际上,LoadConversationService() 不仅仅是创建一个新对象,它比这更复杂,这就是为什么我不想从构造函数调用它的原因。我希望它被延迟加载。感谢您对空宽容运算符的建议,但我想知道是否有任何方法可以避免这种情况,因为在我看来,这里不应该需要它。我不认为 conversationService 在 PredictResponse() 时可以为 null,我认为编译器应该理解这一点,但我想它没有?也许我只是错过了什么?
0赞
JDChris100
2/22/2023
我建议,如果 ConversatioinService 对象非常复杂或性能不佳,您可能应该重构它。另一种方法是,就像我说的,制作一个名为 GetConversaionService 的包装器,它加载(如果为 null)并返回 conversaion 服务
0赞
bmo
2/20/2023
#2
您正在尝试从可为 null 的对象访问方法,因此编译器会警告您 conversationService 可能为 null。您可以写信告诉编译器您期望可能为 null。conversationService?.PredictResponse(...)
评论
0赞
Totte
2/21/2023
但是当 PredictResponse() 被调用时,conversationService 不能为空吗?这只是编译器的当前状态,它不理解这一点,我必须手动告诉它它不能为空吗?
评论