C# 动态 POD 是值类型还是引用类型?

Is a C# dynamic POD a value or reference type?

问:在下面的示例中,n 是值还是引用?

dynamic n = (int)2;

默认情况下,除非另有说明:

从概念上讲,上面的值可以被认为是 "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.