话说有一天你要用反射来对Target类进行操作,调用Foo函数。
public class Target
...{
public void Foo(int x, int y, int z)
...{
}

public void Foo(int x, ref int y, out int z)
...{
}
}
可以看到Foo有2个重载,唯一的区别在于第二个Foo方法签名中有带ref的参数。
如果你直接写:

Target myTarget = new Target();
Type t = myTarget.GetType();
MethodInfo methodInfoWithRefParamters = t.GetMethod("Foo");
那么会在RunTime扔个Exception说: Ambiguous match found.
要想invoke第二个Foo的话,我们必须这样写:
MethodInfo methodInfoWithRefParamters = t.GetMethod("Foo", new Type[] ...{typeof(int), Type.GetType("System.Int32&"),Type.GetType("System.Int32&") });
好吧,现在运行是正常运行了,可是新的问题又来了:这个System.Int32&是个啥东东呢?
 
先在MSDN/.Net Reflector找找Int32&,没有。Google和查看微软放出的Framework Source Code,同样无果。
 
得,现成的资料找不到,那只有让我们自己通过做试验来玩玩了。
 
1。 先试试能不能搞一个Int32&的实例出来:

当然,就不用指望直接能在C#里面new一个Int32&了。(如果是unsafe的话,Int32*到还可以)
来试试亲爱的Activator吧:
Type refInt32Type = Type.GetType("System.Int32&");
object myRefInt = System.Activator.CreateInstance(refInt32Type, true);
哎呀,扔了一个“No parameterless constructor defined for this object.”异常出来。
 
2。好吧,那让我们来看看Int32&有啥样的constructor:
BindingFlags bf = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.NonPublic ;
Console.WriteLine(refInt32Type.GetConstructors(bf).Length);
结果却返回了0。

狠一点,把全部BindingFlags Enum放到bf上去呢,用GetMembers试试呢?

BindingFlags bf = // all values of BindingFlags
Console.WriteLine("count of member in type Int32&: {0}", Type.GetType("System.Int32&").GetMembers(bf).Length);
oops,输出长度还是0!(这个地方不知道使用BindingFlags的方法对不对,还请大家指正)
 3。Ok,Ok,不能创建实例就暂时不管它,那让我们用QuickWatch来看看这个Int32&类型有啥属性:

下面是我把Int32,Int32&, Int32*,外加Boolean&类型做对比的结果。(属性值相同的已经略过)


Int32
Int32&
Int32*
Boolean&
Attributes
1057033
NotPublic
NotPublic
NotPublic
BaseType
{"System.ValueType"}
《undefined value》
《undefined value》
《undefined value》
FullName
System.Int32
System.Int32&
System.Int32*
System.Boolean&
GUID
a310fadd-7c33-377c-9d6b-599b0317d7f2
全是0
全是0
全是0
HasElementType
false
true
true
true
IsAutoLayout
false
true
true
true
IsByRef
false
true
true
true
IsClass
false
true
true
true
IsLayoutSequential
true
false
false
false
IsNotPublic
false
true
true
true
IsPointer
false
false
true
false
IsPrimitive
true
false
false
false
IsPublic
true
false
false
false
IsSealed
true
false
false
false
IsSerializable
true
false
false
false
IsValueType
true
false
false
false
 
通过这张表我们可以观察到很有意思的结果:
Int32& 是ByRef的(最明显,呵呵),不是ValueType, 不可以序列化,没有Sealed,GUID都是0,BaseType 显示为《undefined value》
 
请特别注意的是Int32&, Int32*它们IsClass属性为True,说明是个Class,先记下来,在后面我会给大家看一个更有趣的结果。
 
既然,Int32&和Int32*都说自己有ElementType,那就来看看是什么Type吧:
Type.GetType("System.Int32&").GetElementType(); // Print “System.Int32”
Type.GetType("System.Int32*").GetElementType(); // Print “System.Int32” too.
4.回过头来看看生成的IL代码呢?
 

如图,只能看到对于ref/out 的参数,使用的是ldloca.s 指令,还是没看到我们的Int32&类型,
 
5.最后来看看最有趣的发现:
先试试在你的机器上run这3句代码:
Console.WriteLine(Type.GetType("System.Int32&").IsSubclassOf(typeof(object)));
Console.WriteLine(Type.GetType("System.Int32*").IsSubclassOf(typeof(object)));
Console.WriteLine(Type.GetType("System.Boolean*").IsSubclassOf(typeof(object)));
再看结果,呵呵,吃惊吧。以上3句都是输出False。难道说.Net里存在着不是从Object继承的Type吗?可它的IsClass属性是为True的哦~

会不会Int32&不是属于.Net框架的呢?可看看它的AssemblyQualifiedName是“System.Int32&, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”,也没看出什么问题啊?(汗)
 
个人初步猜测:
 
Int32&类型并不是一个真实存在的类型(原因是通过Reflector没能发现它的踪影),而是在CLR中动态构造的一个类型。MS使用它来“表示/标志”某个ValueType的地址。

2005/08/16 Update: 
思归的帖子,以及Joel Pobar的blog对这个问题作出了比较好的解释,有兴趣的读者可以看原文,偷懒的话就听我说一下吧:
 
ByRef types 是受控指针,在CLR里面也是真实存在的类型。不过因为只有很少的IL指令能够作用与它,所以我们不能创建它的实例。同时,系统也限制我们只能在parameter的位置使用ByRef的类型。值得注意的是Int32&和Int32之间不存在什么关系哦...