英文:
C# an error when passing an unassigned out argument
问题
以下是您要翻译的内容:
我在想为什么在以下代码中会出现错误?我正在使用“out”参数将未赋值的整数“x”传递给“foo”。在将其返回给调用方法之前,我还给“x”赋了一个值。
int x;
Foo(out x);
Console.ReadLine();
void Foo(out int y)
{
Console.WriteLine(x); // x is 0
y = 1; // Mutate y
Console.WriteLine(x); // x is 1
}
这很奇怪,因为在以下代码中,我可以使用类似的原理传递未赋值的字符串,并且不会收到任何错误。
string a;
Split("Stevie Ray Vaughn", out a, out _);
Console.WriteLine(a);
void Split(string name, out string firstNames, out string lastName)
{
int i = name.LastIndexOf(' ');
firstNames = name.Substring(0, i);
lastName = name.Substring(i + 1);
}
请注意,我已经将HTML实体字符(如"
和'
)替换为相应的引号字符。
英文:
I was wondering why I get an error in the following code? I am passing an unassigned integer x
to foo
using an out
argument. I also assign a value to x
before returning it to the calling method.
int x;
Foo(out x);
Console.ReadLine();
void Foo(out int y)
{
Console.WriteLine(x); // x is 0
y = 1; // Mutate y
Console.WriteLine(x); // x is 1
}
This is strange because in the following code I can pass an unassigned string using similar principles and don't get back any errors.
string a;
Split("Stevie Ray Vaughn", out a, out _);
Console.WriteLine(a);
void Split(string name, out string firstNames, out string lastName)
{
int i = name.LastIndexOf(' ');
firstNames = name.Substring(0, i);
lastName = name.Substring(i + 1);
}
答案1
得分: 1
以下是您要翻译的内容:
"Console.WriteLine" 方法内部的调用在 "Foo" 方法内部无法编译,除非 "x" 是一个字段,而不是调用方法中的局部变量。
如果 "x" 是一个字段,那么它会自动初始化为默认值,因为它是一个整数,所以默认值是 0。所以这样的代码有点意义。它将编译并按预期运行:
class C
{
int x;
public void M()
{
Foo(out x);
}
void Foo(out int y)
{
Console.WriteLine(x); // x 为 0
y = 1; // 为 y 分配一个值
Console.WriteLine(x); // x 为 1
}
}
这将输出确实是 0 和 1,正如您在SharpLab演示中所见。
然而,如果 "x" 是调用方法中的局部变量,您将在 "Foo" 中的两行尝试使用它的地方收到编译错误:
> 错误 CS0103:名称 'x' 在当前上下文中不存在
现在假设您将这些行中的 "x" 更改为 "y":
class C
{
public void M()
{
int x;
Foo(out x);
}
void Foo(out int y)
{
Console.WriteLine(y);
y = 1;
Console.WriteLine(y);
}
}
这将会发生什么:在调用 Console.WriteLine(y);
的第一行上,您将收到错误消息
> 错误 CS0269:使用未赋值的 out 参数 'y'
但如果您删除对 Console.WriteLine(y);
的第一个调用,一切将正常工作 - 如此演示所示。
因此,总结一下 - 问题不在您认为的地方。
将未赋值的局部变量作为 out 参数传递给方法是完全可以的,只要在第一次分配值之前不使用它们。
英文:
The Console.WriteLine
calls from inside the Foo
method can't compile unless x
is a field, and not a local variable in the calling method.
If x
is a field, then it automatically gets initialized with its default value, and since it's an int, the default value is 0. So code like this kind of makes sense. It will compile and run as you expected:
class C
{
int x;
public void M() {
Foo(out x);
}
void Foo(out int y)
{
Console.WriteLine(x); // x is 0
y = 1; // assing a value to y
Console.WriteLine(x); // x is 1
}
}
The output of this will indeed be 0 and 1 as you can see in this SharpLab demo.
However, if x
was a local variable in the calling method, you'll get compilation errors on the two lines in Foo
that are attempting to use it:
> error CS0103: The name 'x' does not exist in the current context
Here's the SharpLab demo of that.
Now suppose you'll change the x
in these lines to y
:
class C
{
public void M() {
int x;
Foo(out x);
}
void Foo(out int y)
{
Console.WriteLine(y);
y = 1;
Console.WriteLine(y);
}
}
Here's what will happen: You'll get an error on the first line calling Console.WriteLine(y);
> error CS0269: Use of unassigned out parameter 'y'
But if you remove the first call to Console.WriteLine(y);
, everything will work perfectly - as shown in this demo.
So, to conclude - the problem is not where you thought it was.
It's absolutely fine to pass down unassigned local variables as out parameters to methods, as long as you're not using them before their first assigned a value.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论