为什么要在将结构体传递给函数之前初始化它?
本文关键字:函数 初始化 结构体 为什么 | 更新日期: 2023-09-27 17:53:50
考虑以下代码:
MyStruct j;
j.I = 3;
Console.WriteLine(j.I);
现在看看这个方法:
public static void StructMod(MyStruct ms)
{
ms.I += 100;
Console.WriteLine(ms.I);
}
当我们将MyStruct
传递给方法时,应该在传递之前初始化它吗?例如:
MyStruct j = new MyStruct()
除非
struct
是值类型?
MSDN的第一行:
与单个变量一样,结构体必须在被完全初始化后才能使用。考虑:结构类型是一个值类型…
struct Foo
{
public int Bar;
public int Pop;
}
class Program
{
static void Main(string[] args) {
Foo f;
f.Bar = 3;
test(f); // ERROR: Use of unassigned local variable 'f'
}
static void test(Foo f) {
Console.WriteLine("{0}", f.Bar);
}
}
这里的解决方案是初始化.Bar
,或者简单地调用Foo
构造函数f = new Foo()
,它将所有成员初始化为默认值。
这与在struct
s中添加参数化构造函数时得到的"Field ... must be fully assigned before control is returned to the caller"
错误背后的逻辑相同。
经过一些测试,似乎无论您声明它的方式如何,它都被初始化了。
调用new ...
的一个原因是执行构造函数中的代码(如果有的话)。
从MSDN中获取这个示例,例如:
public struct CoOrds
{
public int x, y;
public CoOrds(int p1, int p2)
{
x = p1;
y = p2;
}
}
你可以这样做,并使用c
,但x
和y
将是0
。
CoOrds c;
或者,您可以这样做,然后x
和y
以值开始。
CoOrds c = new CoOrds(5,3);
(如果actor做了一些更有趣的事情,这将更有用)
如果您希望结构体具有特定的值,则将其初始化为该值。
如果您希望将结构体初始化为其默认值,则不需要显式初始化它。但是,如果结构体的默认值不明显,为了可读性起见,最好还是这样做。
作为旁注:可变结构真的很糟糕;您在示例中提出的整个场景是一种代码气味。参见为什么可变结构是"邪恶的"?
使用不可变结构体可以更安全地实现相同的行为,如
struct MyStruct
{
public readonly int I;
public MyStruct(int i_initial)
{
I = i_initial;
}
}
MyStruct j = new MyStruct(3);
public static void StructMod(MyStruct ms)
{
Console.WriteLine(ms.I + 100);
}
特别要注意,从调用者的角度来看,这个函数的行为将与问题中的行为完全相同,因为结构体是按值传递的,与int
等原语的传递方式相同。如果StructMod中的"Mod"在那里是因为您希望该函数修改值,那么这是一个很好的具体示例,说明为什么通常将可变类型作为对象而不是结构体更好。