有没有办法欺骗编译器允许这个?

时间:2018-04-12 15:54:30

标签: c# .net visual-studio xaml

我有一个等同于

的XAML工作流程
Bar bar;

if (foo.SomeFlag)
{
    // ... do stuff

    bar = .. // set bar, guaranteed unless exception thrown earlier in this block
}

// do other stuff 

// here it is guaranteed that foo.SomeFlag is the same as it was before
if (foo.SomeFlag)
{
   // use bar
}

在简单的C#中,我是如何重写它的。问题是我得到Use of unassigned variable 'bar' ..编译器错误。我理解错误,但我想我可以通过写

来克服它
Bar bar;

const bool someFlag = foo.SomeFlag;

if (someFlag)
{
    // ... do stuff

    bar = .. // set bar, guaranteed unless exception thrown earlier in this block
}

// do other stuff 

if (someFlag)
{
   // use bar
}

但显然这不是有效的语法。

任何想法如何克服?

3 个答案:

答案 0 :(得分:2)

编译器要求bar在使用之前设置为某个值,并且someFlag可能会在if块之间发生变化(意味着第一个块可能无法运行)但第二个块可以),它会给你一个错误。为避免这种情况,您最初可以将bar设置为默认值:

Bar bar = default(Bar);   // this will be 'null' for class objects

然后其余代码应按预期工作

const bool someFlag = foo.SomeFlag;

if (someFlag)
{
    // Do something, assign bar to new value
    bar = new Bar();
}

// Do some other stuff 

// Possibly add a check that bar was set, just to be safe...
if (someFlag && bar != null)
{
    // Use bar
    bar.DoSomething();
}

答案 1 :(得分:0)

欺骗编译器允许它将意味着您的解决方案将有机会发生异常。

想想,如果foo.SomeFlag不正确会发生什么? bar的值将为null或更具体,它将是默认值(Bar)。 (是的,编译器知道任何类型的默认值是什么)。如果,就像我认为你想要的那样,Bar是一个类,那么值肯定是null。然后当它尝试使用bar时,让我们说你试试吧。它会引发异常。编译器实际上是在保护你免受攻击。

在使用bar之前,解决方案只是一个空检查。像:

if (someFlag)
{
   if(bar != null)
   {
       // use bar
   }
}

尽管如此,我强烈建议您开始初始化变量,以便您确定并且不会忘记。像:

解决方案1:用某事开始吧。

Bar bar = null; // <- Only if you know for sure Bar is a class
// or
Bar bar = default(Bar);

if (foo.SomeFlag)
{
    ...
}

解决方案2:制作其他

if (foo.SomeFlag)
{
   ...
}
else
{
    bar = null; // <- Only if you know for sure Bar is a class
    // or
    bar = default(bar);
}
...

答案 2 :(得分:0)

编译器不够聪明,无法识别您的if块是否实际执行。因此,它假定bar在使用之前可能无法初始化。要缓解此问题,只需将bar初始值设为null或提供else语句即可。

Bar bar = null;

const bool someFlag = foo.SomeFlag;

if (someFlag)
{
    // ... do stuff

    bar = .. // set bar, guaranteed unless exception thrown earlier in this block
}

// do other stuff 

if (someFlag)
{
   // use bar
}

或者:

Bar bar;

const bool someFlag = foo.SomeFlag;

if (someFlag)
{
    // ... do stuff

    bar = .. // set bar, guaranteed unless exception thrown earlier in this block
}
else
{
    bar = null;
}

// do other stuff 

if (someFlag)
{
   // use bar
}