关于 sealed 和 virtual 的问题

microblue 2004-04-19 03:56:35
使用 Wincv.exe 查看得到:

public interface _AppDomain
{
object GetData(string name);
// ...
}

public sealed class AppDomain : MarshalByRefObject, _AppDomain, System.Security.IEvidenceFactory
{
public virtual object GetData(string name);
// ...
}

我们知道:
1. 密封类不能被继承。
2. 虚拟方法的实现可以由派生类取代。

既然密封类不能被继承, 那么在密封类中的虚拟方法有什么意义?

请各位大侠予以指点。 :)
...全文
136 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
flyingbirddhp 2004-04-22
  • 打赏
  • 举报
回复
接口中的非static方法默认是public virtual的,如果实现类实现方法时没有加virtual,那么该方法就变成sealed了,就是派生类不能重写了。
但AppDomain本身就是sealed啊,就算不加virtual也应该没有什么影响啊
迷惑~~~~~~~~
lizhongkun 2004-04-22
  • 打赏
  • 举报
回复
right!! this a bug!
microblue 2004-04-22
  • 打赏
  • 举报
回复
同意 qqchen79(知秋一叶 [MS MVP]) 的看法。
这样看来,不但 WinCV.EXE 有 bug,而且 MSDN 文档中很多地方也不恰当地使用 virtual 关键字,也是错误的。
qqchen79 2004-04-22
  • 打赏
  • 举报
回复
C#里面从Interface继承并且没有使用virtual关键字的函数在MSIL里面对应virtual final,final保证这个函数不会被其子类override,也就保证了JIT可以使用直接方法调用,不需要虚函数解析。

wincv看上去使用的是C#语法,那么这就是wincv的bug了。:)

==============================
http://blog.joycode.com/qqchen
tongcheng 2004-04-21
  • 打赏
  • 举报
回复
学习
up
Aglie 2004-04-20
  • 打赏
  • 举报
回复
学习~
wolftop 2004-04-20
  • 打赏
  • 举报
回复
学习学习`1
juqiang 2004-04-20
  • 打赏
  • 举报
回复
做个记号先!!!
yzx110 2004-04-20
  • 打赏
  • 举报
回复
也就是说代码里面不要写virtual,编译成il后会自动加上virtual
microblue 2004-04-20
  • 打赏
  • 举报
回复
请各位大侠发表高见
microblue 2004-04-20
  • 打赏
  • 举报
回复
我写了一段程序程序:
// test1.cs
using System;

namespace Benben.Other.Test1
{
interface ITest
{
object GetData(string name);
}

sealed class Test1 : ITest
{
public object GetData(string name) // 加上virtual编译时会出错
{
return name.Clone();
}
}

class Test2 : ITest
{
public virtual object GetData(string name)
{
return name.Clone();
}
}
}
用 csc /t:library test1.cs 编译, 然后用 ildasm test1.dll 查看:

ITest 接口描述如下:
.class interface private abstract auto ansi ITest
其 GetData 方法描述如下:
.method public hidebysig newslot abstract virtual
instance object GetData(string name) cil managed

Test1 类描述如下:
.class private auto ansi sealed beforefieldinit Test1
extends [mscorlib]System.Object
implements Benben.Other.Test1.ITest
其 GetData 方法描述如下:
.method public hidebysig newslot virtual final
instance object GetData(string name) cil managed

Test2 类描述如下:
.class private auto ansi beforefieldinit Test2
extends [mscorlib]System.Object
implements Benben.Other.Test1.ITest
其 GetData 方法描述如下:
.method public hidebysig newslot virtual
instance object GetData(string name) cil managed

可以看出, 三个 GetData 方法均有 virtual 关键字修饰
microblue 2004-04-20
  • 打赏
  • 举报
回复
我用 ILDASM.EXE 反汇编 C:\WINNT\Microsoft.NET\Framework\v1.1.4322\mscorlib.dll ,得到以下结果:

_AppDomain 接口的描述如下:
.class interface public abstract auto ansi _AppDomain
其 GetData 方法描述如下:
.method public hidebysig newslot abstract virtual
instance object GetData(string name) cil managed

AppDomain 类描述如下:
.class public auto ansi sealed beforefieldinit AppDomain
extends System.MarshalByRefObject
implements System._AppDomain,
System.Security.IEvidenceFactory
其 GetData 方法描述如下:
.method public hidebysig newslot virtual final
instance object GetData(string name) cil managed

可以看出,两个方法均有 virtual 关键字修饰。
microblue 2004-04-20
  • 打赏
  • 举报
回复
我认为实际上,AppDomain 密封类的 GetData 方法按 C# 语法是不用 virtual 关键字修饰的。但该方法的 CLR 元数据特性中是有 virtual 特性的。也就是说,MSDN 和 WinCV.exe 程序都错误地把 CLR 的 virtual 元数据特性解释成了 C# 的 virtual 关键字(用来修饰 GetData 方法)。
Essential .NET Volume 1: The Common Language Runtime 中给出了三个表论述 CLR 元数据特性及其和 C# 关键字的关系。这里无法贴表格,请大家参见:
http://www.coreader.com/Page/Document.aspx?DOCUMENTID=33
以上看法如有不当之处,恳请各位大侠指正。
Dlwxn 2004-04-20
  • 打赏
  • 举报
回复
学习
microblue 2004-04-19
  • 打赏
  • 举报
回复
谢谢各位大侠的关注!
不光是 MSDN 的问题,因为 MSDN 文档可能出错。 但 c:\Program Files\Microsoft.NET\SDK\v1.1\Bin\WinCV.exe 是一个使用反射来查看 .NET Framework 类库代码的程序,它反映了 FCL 的真实情况。
请各位大侠继续发表意见。
谢谢!
ljyzc 2004-04-19
  • 打赏
  • 举报
回复
學習!
Lostinet 2004-04-19
  • 打赏
  • 举报
回复
奇怪
sscli上的确代码不是virtual的啊 .

http://www.123aspx.com/rotor/rotorsrc.aspx?rot=39775

huangsuipeng 2004-04-19
  • 打赏
  • 举报
回复
好象好似有问题噢,帮顶!
GZ
bitsbird 2004-04-19
  • 打赏
  • 举报
回复
gz
CMIC 2004-04-19
  • 打赏
  • 举报
回复
public interface _AppDomainA
{
object GetData(string name);
}
public sealed class AppDomainA : _AppDomainA
{
public virtual object GetData(string name)
{
}
}
上面这段代码编译时.Net提示错误:D:\MyDoc\Learn\CSharp\WindowsApplication1\Form1.cs(353): “WindowsApplication1.AppDomainA.GetData(string)”是密封类“WindowsApplication1.AppDomainA”中新虚拟成员,编译不过去,而MSDN中
public sealed class AppDomain : MarshalByRefObject, _AppDomain,
IEvidenceFactory


[C#]
public virtual object GetData(
string name
)函数确实和楼主写的一样
但我用Reflector反编译AppDomain 的GetData函数结果却是这样的:
public object GetData(string name)
{ int num1;
int num2;
if (name == null)
{
throw new ArgumentNullException("name");

}
num1 = AppDomainSetup.Locate(name);
if (num1 == -1)
{
if (name.Equals(AppDomainSetup.LoaderOptimizationKey))
{
return this.FusionStore.LoaderOptimization;
}
return this.LocalStore[name];
}
num2 = num1;
switch (num2)
{
case 0:
{
goto L_0085;

}
case 1:
{
goto L_0091;

}
case 2:
{
goto L_009D;

}
case 3:
{
goto L_00A9;

}
case 4:
{
goto L_00B5;

}
case 5:
{
goto L_00C1;

}
case 6:
{
goto L_00CD;

}
case 7:
{
goto L_00D9;

}
case 8:
{
goto L_00E5;

}
case 9:
{
goto L_00F1;

}
case 10:
{
goto L_00FD;

}
case 11:
{
goto L_0109;

}
case 12:
{
goto L_011A;

}

}
goto L_012B;

L_0085:
return this.FusionStore.ApplicationBase;
L_0091:
return this.FusionStore.ConfigurationFile;
L_009D:
return this.FusionStore.DynamicBase;
L_00A9:
return this.FusionStore.DeveloperPath;
L_00B5:
return this.FusionStore.ApplicationName;
L_00C1:
return this.FusionStore.PrivateBinPath;
L_00CD:
return this.FusionStore.PrivateBinPathProbe;
L_00D9:
return this.FusionStore.ShadowCopyDirectories;
L_00E5:
return this.FusionStore.ShadowCopyFiles;
L_00F1:
return this.FusionStore.CachePath;
L_00FD:
return this.FusionStore.LicenseFile;
L_0109:
return this.FusionStore.DisallowPublisherPolicy;
L_011A:
return this.FusionStore.DisallowCodeDownload;
L_012B:
return null;
}
不知道真的是不是MSDN错了。



加载更多回复(1)

17,740

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧