提问人:Jez 提问时间:11/11/2023 最后编辑:winscripterJez 更新时间:11/13/2023 访问量:92
代码分析无法确定此变量已设置是否有技术原因?
Is there a technical reason why code analysis can't figure out that this variable has been set?
问:
我正在对等待的 lambda 中的引用类型变量进行初始赋值,如下所示:
private class TestClass {
public int TestInt;
}
public async Task TestMethod() {
TestClass testVar;
await Task.Run(() => {
testVar = new();
});
var testInt = testVar.TestInt;
}
但是,最后一行给出错误“使用未分配的局部变量'testVar'”。是否有技术原因导致 C# 的代码分析无法确定变量在该点之前已保证已分配?在我第一次使用的地方使用运算符有点烦人。如果我需要首先在等待的 lambda 中分配变量,并且不能方便地给它一个默认赋值(这是一个相当复杂的类),有什么方法可以解决这个问题?!
testVar
答:
1赞
PMF
11/11/2023
#1
这似乎不是 async/await 问题,而是 lambda 表达式的一般问题。编译器似乎无法遵循 lambda 的路径来检测赋值。
此代码也不编译:
private class TestClass
{
public int TestInt;
}
public void TestMethod()
{
TestClass testVar;
Action a = new Action(() =>
{
testVar = new();
});
a.Invoke();
var testInt = testVar.TestInt; // Same here: "testVar" is not initialized
}
因此,我首先认为编译器通常无法跟踪方法边界上的赋值,但以下代码令人惊讶地没问题:
public void TestMethod()
{
TestClass testVar;
void Foo()
{
testVar = new();
}
Foo();
var testInt = testVar.TestInt; // No more complaints!
}
因此,这似乎是编译器对 lambda 函数的一些限制,但为什么 - 我说不出来。
2赞
Jez
11/12/2023
#2
基本上,这样做的原因是 C# 流分析无法知道传入的 lambda(或任何等待的获取 lambda 的方法)将在完成时确定执行,因此它不会假设它会执行。出于这个原因,我需要初始化变量,以断言在我访问它时它将是非空的,以摆脱警告/错误。Task.Run
await
TestClass testVar = null!;
评论
testVar
null
testVar
null!
var testVar = await Task.Run(() => { TestVar x = new(); return x; });
async void