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

推荐订阅源

CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Project Zero
Project Zero
N
Netflix TechBlog - Medium
P
Privacy International News Feed
Cisco Talos Blog
Cisco Talos Blog
Recorded Future
Recorded Future
C
Cybersecurity and Infrastructure Security Agency CISA
The Register - Security
The Register - Security
P
Palo Alto Networks Blog
GbyAI
GbyAI
量子位
Simon Willison's Weblog
Simon Willison's Weblog
Cyberwarzone
Cyberwarzone
M
MIT News - Artificial intelligence
T
Threatpost
腾讯CDC
MyScale Blog
MyScale Blog
P
Privacy & Cybersecurity Law Blog
罗磊的独立博客
博客园 - 叶小钗
V
V2EX
美团技术团队
NISL@THU
NISL@THU
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
C
Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
Google Online Security Blog
Google Online Security Blog
PCI Perspectives
PCI Perspectives
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
爱范儿
爱范儿
G
Google Developers Blog
博客园 - Franky
P
Proofpoint News Feed
T
The Blog of Author Tim Ferriss
B
Blog
Spread Privacy
Spread Privacy
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Latest news
Latest news
The GitHub Blog
The GitHub Blog
T
Threat Research - Cisco Blogs
D
DataBreaches.Net
F
Full Disclosure
L
LINUX DO - 热门话题
Stack Overflow Blog
Stack Overflow Blog
Scott Helme
Scott Helme
C
CERT Recently Published Vulnerability Notes
Jina AI
Jina AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Fortinet All Blogs

博客园 - 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之间不存在什么关系哦...