看到同站博客linkcd很有趣的问题,虽有点直感,但因对CLR研究不深,所以Google了一下,看到了CLR开发组项目经理Joel Pobar的blog《CLR Type System notes》。他从Reflection的角度对ReferenceType,ValueType,Primitive (Scalar types),Enum,Array,ByRef,TypedRef,(unmanaged) Pointer,COMObject,Interface,TransparentProxy,Delegate等类型做了分析。跟问题有关的是其中的byref类型,对此,他是这么说的



ByRef types are managed pointers. ByRef don’t box and there are very few IL instruction that can be performed on ByRef types (i.e. ldind.ref, stind.ref). Because of that restriction there is never an instance of a ByRef type as far as reflection is concerned. However ByRef types are real, concrete types in the type system. Inspecting a method that takes a ByRef arg will reveal a unique type that is in no relationship with the type it represents (i.e. int& and int are in no relationship).

Reflection simulates ByRef and it’s the user responsibility to fetch the updated value out of the argument array used in reflection invocation. Verifiable IL ensures that ByRef types are only used in argument position. Usage of ByRef in any other location (return value, fields) results in unverifiable code.

Interesting features of ByRef

ChangeMyString(ref string s)

How do I discover via Reflection? When Reflection takes it as an argument (new Object[] myref) to late bound invoke a method that takes a reference, Reflection actually passes the object array, the method (invoked latebound) modifies the array reference instead of the actual ByRef variable that we wanted to modify…..”

翻了一下ECMA-335: CLI Partition I – Architecture的原文,第八章《Common Type System》对byref的定义:

“…..The byref constraint states that the content of the corresponding location is a managed pointer. A managed pointer may point to a local variable, parameter, field of a compound type, or element of an array…..”