C# 动态 POD 是值类型还是引用类型?
Is a C# dynamic POD a value or reference type?
问:在下面的示例中,n
是值还是引用?
dynamic n = (int)2;
默认情况下,除非另有说明:
Class 实例和数组是引用类型。
POD 类型,可能还有结构,都是值类型。
从概念上讲,上面的值可以被认为是 "dynamic POD type" 或 "dynamic type containing a POD",无论哪种方式,上面的哪条规则应该适用并不明显,如果它们都适用,这可能导致矛盾。
对我来说,dynamic
感觉好像它应该表现得像它所持有的值,否则就是一个引用类型。
令人愉快的是,他们似乎是他们持有的那种类型。
dynamic n = (int)2;
is
一个值类型。
dynamic n = new int[0];
is
引用类型。
dynamic n = 4;
bool b = n is ValueType; // true
n = new int[0];
b = n is ValueType; // false
请参阅 NineBerry
的答案,了解使用结构成员而不使用 is
的另一种示例。
考虑这个例子:
struct TestStruct
{
public int Value;
}
private void button1_Click(object sender, EventArgs e)
{
TestStruct lOriginal = new TestStruct();
lOriginal.Value = 42;
dynamic n = lOriginal;
dynamic m = n;
lOriginal.Value = "4711"
MessageBox.Show(m.Value.ToString());
n.Value = 4711;
MessageBox.Show(m.Value.ToString());
}
第一个输出是“42”。第二个输出是“4711”。所以当给动态变量赋值类型时,值类型的行为就像一个值类型,进行复制。但是当您随后使用动态变量时,它表现为引用类型,仅在分配给另一个动态变量时复制引用。
dynamic
等同于 object
。实际上,如果你使用反编译器(例如 ILDasm),你会看到
object n = 2
或者如果您更喜欢 IL 代码
.locals init (
[0] object
)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: box [mscorlib]System.Int32
IL_0007: stloc.0
所以 n
是对象,它是一个引用类型。是的,你在这里有拳击。甚至 C# 规范也说 dynamic 可以被认为等同于 object (4.7 The dynamic type):
dynamic is considered identical to object except in the following
respects:
• Operations on expressions of type dynamic can be dynamically bound (§7.2.2).
• Type inference (§7.5.2) will prefer dynamic over object if both are candidates.
问:在下面的示例中,n
是值还是引用?
dynamic n = (int)2;
默认情况下,除非另有说明:
Class 实例和数组是引用类型。
POD 类型,可能还有结构,都是值类型。
从概念上讲,上面的值可以被认为是 "dynamic POD type" 或 "dynamic type containing a POD",无论哪种方式,上面的哪条规则应该适用并不明显,如果它们都适用,这可能导致矛盾。
对我来说,dynamic
感觉好像它应该表现得像它所持有的值,否则就是一个引用类型。
令人愉快的是,他们似乎是他们持有的那种类型。
dynamic n = (int)2;
is
一个值类型。
dynamic n = new int[0];
is
引用类型。
dynamic n = 4;
bool b = n is ValueType; // true
n = new int[0];
b = n is ValueType; // false
请参阅 NineBerry
的答案,了解使用结构成员而不使用 is
的另一种示例。
考虑这个例子:
struct TestStruct
{
public int Value;
}
private void button1_Click(object sender, EventArgs e)
{
TestStruct lOriginal = new TestStruct();
lOriginal.Value = 42;
dynamic n = lOriginal;
dynamic m = n;
lOriginal.Value = "4711"
MessageBox.Show(m.Value.ToString());
n.Value = 4711;
MessageBox.Show(m.Value.ToString());
}
第一个输出是“42”。第二个输出是“4711”。所以当给动态变量赋值类型时,值类型的行为就像一个值类型,进行复制。但是当您随后使用动态变量时,它表现为引用类型,仅在分配给另一个动态变量时复制引用。
dynamic
等同于 object
。实际上,如果你使用反编译器(例如 ILDasm),你会看到
object n = 2
或者如果您更喜欢 IL 代码
.locals init (
[0] object
)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: box [mscorlib]System.Int32
IL_0007: stloc.0
所以 n
是对象,它是一个引用类型。是的,你在这里有拳击。甚至 C# 规范也说 dynamic 可以被认为等同于 object (4.7 The dynamic type):
dynamic is considered identical to object except in the following respects:
• Operations on expressions of type dynamic can be dynamically bound (§7.2.2).
• Type inference (§7.5.2) will prefer dynamic over object if both are candidates.