我的问题是理论性的,请不要建议对代码进行编辑或替代。
我有如下方法:
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是否可以安全返回。
答案 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}}?