.net 代码分析不能发现这个变量已经被设置了,这有技术上的原因吗?

unguejic  于 2023-11-20  发布在  .NET
关注(0)|答案(2)|浏览(168)

我在一个等待的lambda中对我的引用类型变量进行初始赋值,如下所示:

  1. private class TestClass {
  2. public int TestInt;
  3. }
  4. public async Task TestMethod() {
  5. TestClass testVar;
  6. await Task.Run(() => {
  7. testVar = new();
  8. });
  9. var testInt = testVar.TestInt;
  10. }

字符串
然而,最后一行给出了错误“Use of unassigned local variable 'testVar'”。C#的代码分析不能确定变量在该点被赋值是否有技术原因?在第一次使用testVar的地方使用!操作符有点烦人。如果我需要首先在内部分配变量,有什么方法可以解决这个问题吗?一个等待的lambda,不能方便地给予它一个默认赋值(它是一个相当复杂的类)?

col17t5w

col17t5w1#

基本上,这是因为C#流分析无法知道传入Task.Run的lambda(或任何等待的接受lambda的方法)将在await完成时被执行,所以它不会假设它会被执行。出于这个原因,我需要用TestClass testVar = null!;初始化变量,以Assert在我访问它时它将是非空的,以消除警告/错误。

mbskvtky

mbskvtky2#

看起来这不是一个lambda/await问题,而是一个lambda表达式的一般问题。编译器似乎无法遵循lambda的路径来检测赋值。
这段代码也无法编译:

  1. private class TestClass
  2. {
  3. public int TestInt;
  4. }
  5. public void TestMethod()
  6. {
  7. TestClass testVar;
  8. Action a = new Action(() =>
  9. {
  10. testVar = new();
  11. });
  12. a.Invoke();
  13. var testInt = testVar.TestInt; // Same here: "testVar" is not initialized
  14. }

字符串
所以我首先想到编译器通常无法跟踪方法边界上的赋值,但下面的代码令人惊讶地是可以的:

  1. public void TestMethod()
  2. {
  3. TestClass testVar;
  4. void Foo()
  5. {
  6. testVar = new();
  7. }
  8. Foo();
  9. var testInt = testVar.TestInt; // No more complaints!
  10. }


所以这似乎是编译器对lambda函数的一些限制,但为什么-我不知道。

展开查看全部

相关问题