惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
L
LINUX DO - 热门话题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
V
V2EX
GbyAI
GbyAI
量子位
Microsoft Azure Blog
Microsoft Azure Blog
有赞技术团队
有赞技术团队
G
Google Developers Blog
云风的 BLOG
云风的 BLOG
B
Blog
Microsoft Security Blog
Microsoft Security Blog
S
SegmentFault 最新的问题
O
OpenAI News
N
News and Events Feed by Topic
博客园 - Franky
爱范儿
爱范儿
Forbes - Security
Forbes - Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V2EX - 技术
V2EX - 技术
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
News and Events Feed by Topic
N
News | PayPal Newsroom
Schneier on Security
Schneier on Security
Cloudbric
Cloudbric
Security Archives - TechRepublic
Security Archives - TechRepublic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Recent Commits to openclaw:main
Recent Commits to openclaw:main
人人都是产品经理
人人都是产品经理
P
Privacy International News Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog RSS Feed
阮一峰的网络日志
阮一峰的网络日志
D
DataBreaches.Net
Last Week in AI
Last Week in AI
罗磊的独立博客
Spread Privacy
Spread Privacy
Recent Announcements
Recent Announcements
The Cloudflare Blog
Google DeepMind News
Google DeepMind News
AWS News Blog
AWS News Blog
The Register - Security
The Register - Security
Y
Y Combinator Blog
J
Java Code Geeks
I
Intezer

博客园 - linkcd

linkcd胡扯职业生涯规划(二): 关于 人 linkcd胡扯职业生涯规划(一): 关于定位 如何才能用好Email? 让Switch-Case/If-Else-If-Else从你系统中走开 [翻译]每个作者都应该懂的统计学 Part I Castle.MircoKernel Class Diagram - Part I 一个不错的scheme入门PPT 人格类型 测试结果 .Net 2.0 下Data Container性能比较: Binary Serialize Dataset vs Custom Classes 智能替换DataTable.Select中会导致错误的单引号 - linkcd - 博客园 Nullable Type is an immutable type Why does Dataset NOT serialize its BinaryFormat property? (ADO.net 2.0) Undocumented Keywords in C# 《4个程序员的一天》(续) 由idior的问题想到的 回FantasySoft 4个程序员的一天 n久以前写的火星文 Solution for SICP 在Vs.net中集成 NDoc生成的 Html Help 2帮助文档
System.Int32&是个啥?
linkcd · 2005-08-14 · via 博客园 - linkcd

话说有一天你要用反射来对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之间不存在什么关系哦...