不从 System.Object 继承之后

探讨了IL允许创建不继承自System.Object的类的原因及其带来的挑战,特别是在C#中的应用和潜在问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不从 System.Object 继承之后

Written by Allen Lee

上一篇文章说到 IL 允许创建一个不继承自 System.Object 的类,这打破了我们已有的一些认识。到了这个份上,我们自然会追问,为什么要允许这种类型存在呢?

考察如下 C++/CLI 代码:

1 None.gif using namespace System;
2 None.gif
3 None.gif public ref class Person
4 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
5InBlock.gifpublic:
6InBlock.gifPerson(String^name)
7ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
8InBlock.gifm_Name=name;
9ExpandedSubBlockEnd.gif}

10InBlock.gif
11InBlock.gifPerson(Person%p)
12ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
13InBlock.gifm_Name=p.Name;
14ExpandedSubBlockEnd.gif}

15InBlock.gif
16InBlock.gifpropertyString^Name
17ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
18InBlock.gifString^get()
19ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
20InBlock.gifreturnm_Name;
21ExpandedSubBlockEnd.gif}

22ExpandedSubBlockEnd.gif}

23InBlock.gif
24InBlock.gifprivate:
25InBlock.gifString^m_Name;
26ExpandedBlockEnd.gif}
;
27 None.gif
28 None.gif void DisplayPersonInfo(Personp)
29 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
30InBlock.gifConsole::WriteLine("Name:{0}",p.Name);
31ExpandedBlockEnd.gif}

32 None.gif
33 None.gif int main(array < System::String ^> ^ args)
34 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
35InBlock.gifPerson^p=gcnewPerson("Allen");
36InBlock.gifDisplayPersonInfo(*p);
37InBlock.gif
38InBlock.gifreturn0;
39ExpandedBlockEnd.gif}

DisplayPersonInfo 方法只能用在 C++/CLI 中,你无法在 C# 中对引用类型进行解引用,就像第三十六行那样。为了处理 C++/CLI 的特性,IL 引入了不少别的语言无法使用的东西。

或许,如同部分评论所言,此举乃是为某些语言的特性埋下伏笔。然而,此举却为 C# 带来了麻烦。我用上一篇文章里所说的方法创建了一个不继承自 System.Object 的 NoInherit 类,置于 NoInherit.dll 中,然后用 Visual Studio 2005 新建一个项目,引用 NoInherit.dll,并在 Main 里写下这些代码:

1 None.gif Typet = typeof (NoInherit);
2 None.gifConsole.WriteLine(t.BaseType == null );
3 None.gif
4 None.gifNoInheritni = new NoInherit( " NoInherit " );
5 None.gif object o = ni as object ;
6 None.gif if (o != null )
7 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
8InBlock.gifConsole.WriteLine(o.GetType());
9InBlock.gifConsole.WriteLine(o.ToString());
10ExpandedBlockEnd.gif}

你猜上面代码的运行结果是什么?正常来说,运行结果应该只有一个 true,即第二行的输出,但事实上,第八行居然正确输出“NoInherit”,而第九行则抛出 AccessViolationException。按道理,第九行的异常是意料中事,但第二行和第五行的结果就很矛盾了。第二行输出 true 表明了 NoInherit 类的确没有继承自 System.Object,但第五行却转换成功,否则 o 应该是 null 的。

当一个系统复杂到一定程度,一个看似没问题的改动可能会导致一些看似不相关的问题。当你拿到一个库时,你是假定里面的所有类都继承自 System.Object,还是去验证一下呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值