为什么这段 C# 代码无法编译?
为什么这段 C# 代码无法编译?
public static Dictionary<short, MemoryBuffer> GetBulkCustom(int bufferId,
int startSecond,out int chunksize, out int bardatetime)
{
//const string _functionName = "GetNextBulkWatchData";
UserSeriesCard currentCard = GetUserSeriesCard(bufferId);
Dictionary<short, MemoryBuffer> result = null;
while (currentCard.CurrentSecond <= startSecond)
result = GetBulk(bufferId, out chunksize, out bardatetime);
if (result == null)
{
result = currentCard.UserBuffer;
chunksize = currentCard.ChunkSize;
bardatetime = currentCard.CurrentBarDateTime;
}
return result;
}
错误:
The out parameter 'bardatetime' must be assigned to before control leaves the current method
The out parameter 'chunksize' must be assigned to before control leaves the current method
我无法想到 bardatetime 和 chunksize 最终未分配的情况。
编辑。我通过将代码调整为逻辑上等效的代码来修复此错误。老实说,我想避免多重分配。
public static Dictionary<short, MemoryBuffer> GetBulkCustom(int bufferId, int startSecond,out int chunksize, out int bardatetime )
{
const string _functionName = "GetNextBulkWatchData";
UserSeriesCard currentCard = GetUserSeriesCard(bufferId);
Dictionary<short, MemoryBuffer> result = null;
chunksize = currentCard.ChunkSize;
bardatetime = currentCard.CurrentBarDateTime;
while (currentCard.CurrentSecond <= startSecond)
result = GetBulk(bufferId, out chunksize, out bardatetime);
if (result == null)
result = currentCard.UserBuffer;
return result;
}
Why is this C# code not compiling?
public static Dictionary<short, MemoryBuffer> GetBulkCustom(int bufferId,
int startSecond,out int chunksize, out int bardatetime)
{
//const string _functionName = "GetNextBulkWatchData";
UserSeriesCard currentCard = GetUserSeriesCard(bufferId);
Dictionary<short, MemoryBuffer> result = null;
while (currentCard.CurrentSecond <= startSecond)
result = GetBulk(bufferId, out chunksize, out bardatetime);
if (result == null)
{
result = currentCard.UserBuffer;
chunksize = currentCard.ChunkSize;
bardatetime = currentCard.CurrentBarDateTime;
}
return result;
}
Errors:
The out parameter 'bardatetime' must be assigned to before control leaves the current method
The out parameter 'chunksize' must be assigned to before control leaves the current method
I can't think of a case where bardatetime and chunksize will end up unassigned..
Edit. I fixed this error by adjusting the code to a logically equivalent one. Honestly I wanted to avoid multiple assigments.
public static Dictionary<short, MemoryBuffer> GetBulkCustom(int bufferId, int startSecond,out int chunksize, out int bardatetime )
{
const string _functionName = "GetNextBulkWatchData";
UserSeriesCard currentCard = GetUserSeriesCard(bufferId);
Dictionary<short, MemoryBuffer> result = null;
chunksize = currentCard.ChunkSize;
bardatetime = currentCard.CurrentBarDateTime;
while (currentCard.CurrentSecond <= startSecond)
result = GetBulk(bufferId, out chunksize, out bardatetime);
if (result == null)
result = currentCard.UserBuffer;
return result;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
如果 while 循环和“if 语句”主体从未输入,则不会分配 out 参数。
从逻辑上来说,您可能知道这些代码路径将始终被输入。 编译器不知道这一点。编译器认为每个具有非恒定条件的“if”和“while”都可以输入或跳过。
在这种情况下,编译器可以进行更复杂的流分析。分析是“在‘if’之前,结果要么为空,要么不为空;如果为空,则‘if’主体分配输出参数。如果它不为空,则可能发生的唯一方式是如果‘ while'主体分配了输出参数,因此输出参数被分配。”
这种级别的分析当然是可能的,但规范中描述的现有流分析算法具有一些很好的特性,即它快速、易于理解、易于实现,通常准确并且仅给出误报,而不给出误报。
If the while loop and "if statement" bodies are never entered then the out parameters are not assigned.
It might be the case that logically you know that those code paths will always be entered. The compiler does not know that. The compiler believes that every "if" and "while" that has a not-constant condition can be entered or skipped.
The compiler could in this case do a more sophisticated flow analysis. The analysis is "before the 'if', result is either null or not null; if it is null then the 'if' body assigns the out parameters. If it is not null then the only way that could have happened is if the 'while' body assigned the out parameters, therefore the out parameters are assigned."
That level of analysis is certainly possible, but the existing flow analysis algorithm described in the spec has some nice properties, namely that it is fast, easy to understand, easy to implement, usually accurate and only gives false positives, not false negatives.
您的
out
参数并未在所有代码路径中设置。如果您跳过依赖于和while (currentCard.CurrentSecond <= startSecond)
和if (result = null)
的代码部分,那么您必须进行一些合理的默认设置分配给他们所有人。您可能知道 while 循环至少会执行一次,但编译器不知道这一点。在这种情况下,您可以用
do {//logic} while (//condition);
替代方案替换该循环。如果您不能做到这一点,那么此构造应该使编译器能够检测
out
变量的确定性设置。Your
out
params are not set up in all codepaths. If you skip the sections of code that are contingent on andwhile (currentCard.CurrentSecond <= startSecond)
andif (result = null)
then you must make some sensible default assignment to all of them.You may know for a fact that the
while
loop will execute at least once, but the compiler does not know this. In this case you may be able to replace that loop with ado {//logic} while (//condition);
alternative.If you cannot do that, then this construct should enable the compiler to detect deterministic setting of the
out
variables.并且
它们的参数将不会被分配。
你可以这样做:
and
they out params will not be assigned.
You could do something like this:
分配 chunksize 和 bardatetime 的两个位置都在某种控制语句(while 或 if)内,编译器无法知道是否将输入或注释这些部分。
因此,据编译器所知,这两个输出参数没有保证的分配。
Both of the places where chunksize and bardatetime are assigned are inside some sort of control statement (while or if), which the compiler cannot know if those sections will be entered or note.
As such, there's no guaranteed assignment, as far as the compiler knows, for those two out parameters.
您可能不会想到不会设置这些输出参数,但据编译器所知,(由于您有预检查循环)控制可以在不设置这些参数的情况下退出。
You may not conceive that those out params would not be set, but as far as the compiler knows it is possible (by virtue of you having a pre-check loop) for control to exit without those params being set.
如果
result
为 null,则永远不会分配bardatetime
。声明为out
的参数必须在方法返回之前设置。只需在方法开始时将其初始化为默认值,它应该可以正常工作。If
result
is null,bardatetime
will never be assigned. A parameter declared asout
must be set before the method returns. Just initialize it to a default value at the beginning of the method, it should work fine.如果 currentCard.CardSecond <= startSecond 则 while 循环不会运行,结果将为 null 并且值永远不会被设置。编译器如何知道 .CardSecond 和 startSecond 是什么?
If currentCard.CardSecond <= startSecond the while loop won't run, result will be null and the values will never get set. How does the compiler know what .CardSecond and startSecond will be?
您可以尝试将 while(){} 循环替换为 do{}while() 循环。在这种情况下,分配将得到保证。
You can try to replace the while(){} loop with a do{}while()-loop. In this case the asignment would be guaranteed.
因为对于方法内的编译器来说,就像局部变量一样,输出参数最初被视为未分配,并且必须在使用其值之前明确分配,现在请检查您的
GetBulk
实现。Because for the compiler within a method, just like a local variable, an output parameter is initially considered unassigned and must be definitely assigned before its value is used now check out your implementation of
GetBulk
.当您输入函数时初始化它们。
Initialize them as you enter the function.
只是想指出,使用 ReSharper,插件本身会突出显示什么这段代码有问题。
Just wanted to point out that using ReSharper, the plugin itself would highlight what's wrong with this code.