可以避免分配出值吗?

时间:2018-06-21 05:37:08

标签: c# roslyn

我的问题是理论性的,请不要建议对代码进行编辑或替代。

我有如下方法:

private bool SomeMethod(int D, out SomeStruct SXY) {

    if (D<0) {
         return false;
    }

    SXY = new SomeStruct(D);
    return true;
}

我通过以下方式使用此方法:

if (true) {
    SomeStruct SXY; // Local scope, not used anywhere else.
    if (SomeMethod(12, out SXY)) {
        // Use SXY only when it has a meaningful value
    }
}

编译器抱怨在SomeMethod返回之前未分配SXY out值。

我们可以避免在SomeMethod很明显的情况下避免无用的赋值和结构创建吗?我想,即使对于编译器也是如此,只有在有意义的情况下才使用SXY? 代码分析可以深入到足以在上述情况下进行编译吗?

编辑:

Freggar要求它,我在生产中使用的实际代码如下:

private SomeStruct? SomeMethod(int D) {

    if (D < 0) {
        return null;
    }

    return new SomeStruct(D);
}

称为:

if (true) {
    SomeStruct? SXY = SomeMethod(12);
    if (SXY != null) {
        // Use SXY only when it is not null
    }
}

同样,这只是一个简化的代码,用以证明其要点。 SomeMethod更为复杂,可能在多个位置返回null,也称为不同。我的目的是了解为什么Roslyn无法在不分配SXY的情况下确定SomeMethod是否可以安全返回。

2 个答案:

答案 0 :(得分:2)

从编译器的角度来看,out参数与您的return值之间没有任何关联。因此,它不能也不会做任何编译器魔术。

干净的方法是将您的函数分为先决条件和对象创建部分:

private bool CanCreateSomeStruct(int D) {
    return D >= 0;
}

private SomeStruct CreateSomeStruct(int D) {
    return new SomeStruct(D);
}

然后像这样使用它:

if (CanCreateSomeStruct(D)) {
     SomeStruct SXY = CreateSomeStruct(D);
}

答案 1 :(得分:1)

C#语言的规则既不要求参数为out的任何方法的返回值都为bool,也不要求对返回值赋予任何含义以便可以确定有效性。

对于所有编译器而言,您都知道SomeMethod的两个分支都将为SXY分配一个实际值。然后,bool结果可能意味着指示提供的结果是“实时”值还是由高速缓存获得的值。因此,当前存在一个错误,因为我们忘记了在false分支中分配值,而编译器为我们捕获了一个错误!

这就是为什么该方法的结果没有含义的原因,我们只需要遵循一组更简单的规则-您必须明确分配out参数。 / p>

如果您担心必须通过为default(SomeStruct)分配SXY来占用内存,那么问题可能是struct大于建议的值,应该是{改为{1}}?