微软MSDN 关于 c# 文档有错误!!--来讨论Dispose()

dxj2000yt 2004-09-04 10:21:42

当你定义从Control控件派生的类时,如果你重载实现了public override void Dispose(),
编译时系统会提示:不能重载,因为父类Component中该方法没有virtual,abstract,override
声明。

但是,MSDN文当中,该方法原型声明中是有virtual的。为什么??
...全文
343 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangkang0752 2004-09-06
  • 打赏
  • 举报
回复
大家都很了不起,很努力啊
各位加油!
dxj2000yt 2004-09-06
  • 打赏
  • 举报
回复
To cuike519(marshal(修炼中)):
对于你上次所举的例子,我又有地方不能理解:
{。。。
我想这种实现方式应该是微软的对现在这几个类的实现方式比较准确的模拟(抛开其他的继承类),
上面的MyControl类我继承了IDisposable接口并在MControl里面显式实现了该接口的方法,同时使用new关键字覆盖了父类Component的方法Dispose()。
这种实现是允许的但是在测试类里面IDisposable的实现是不会被执行的。
。。。
}

仍然是最后一句,不知你的侧重点是说什么。 我将你的代码作了修改,就可以执行IDisposable 的Dispose():

public class test
{//测试类
[STAThread]
static void Main(string[] args)
{
IDisposable ctl = new MyControl();
ctl.Dispose();
while(true);
}
}

---------------------------
我的QQ: 84370398 欢迎联系
dxj2000yt 2004-09-06
  • 打赏
  • 举报
回复
To cuike519(marshal(修炼中)):{
直接继承Control不用你重写该方法,所以微软在实现的时候应该使用的是new或者没有声明为可重裁的函数,如果你需要显式实现这个接口可以将你的控件再继承IDisposable接口,这样你可以显示的实现该接口。

dxj2000yt(桃李者):文档连接是有问题,但是你可能犯了一个错误,你仔细看看你在点击Control里面的Dispose以后,链接指的是ms-help://MS.MSDNQTR.2003FEB.1033/cpref/html/frlrfsystemcomponentmodelcomponentclassdisposetopic.htm这里,这个连接是Component类的是一个描述,你再看看该页的标题,说明该页是描述Component类的Dispose方法而不是Control的方法
}

我的意思是说,对于上面最后一句话,对我所说的问题没有任何影响,不管它是Compenent类,还是Control类。如果微软的文档正确,那我就能重载它,不是覆盖(new).
好在我们现在都认为他的文档有问题,那就一切迎刃而解。
应该是书面交流上的的障碍,看的出你很喜欢C#.
另外在哪能看到关于Component的源码?
cuike519 2004-09-06
  • 打赏
  • 举报
回复
你的方法更合适你是使用类型声明对象。
==》IDisposable的实现是不会被执行的。
意思是如果不使用类型转换,使用我的那个方法不能被调用!
ShengNet 2004-09-06
  • 打赏
  • 举报
回复
学习...
saucer 2004-09-05
  • 打赏
  • 举报
回复
gaobud(真是搞不懂)说得对

Component里Dispose()不是virtual, 是这么定义的

public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

它的virtual方法是

protected virtual void Dispose(bool disposing);

所以你只要做

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
//do something
}

Component里的Dispose()会自动调用你的方法

Implementing Finalize and Dispose to Clean Up Unmanaged Resources
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconFinalizeDispose.asp
cuike519 2004-09-05
  • 打赏
  • 举报
回复
==》我认为你对派生继承等概念还不是很清楚。
首先谢谢你直说。同时请你指出上面我说的那一句话使你得出对我如此的评价?

首先要说得是Component里面的Dispose的确不是virtual的。否则一定可以重写,这应该是文档中的一个错误。
我的意思是:
Control里面没有这个方法Dispose,该方法是从Component里面继承来了。
Component里面没有将该方法实现为virtual的,而是一般的函数实现,所以你不能在子类里面重写它(但是可以覆盖)。

其次我做的一个测试项目,该项目模拟微软对前面我们说的接口以及类的继承和实现:
using System;

namespace WindowsApplication1
{
public interface IDisposable {//模拟IDisposable接口
void Dispose();
}

public interface IComponent : IDisposable {//模拟IComponent接口

}

public class Component : IComponent, IDisposable {//模拟Component类
public void Dispose(){
Console.Write(this.ToString());
}
}

public class Control : Component{//模拟Control类
}

public class MyControl:Control,IDisposable{//模拟你的类
void IDisposable.Dispose(){

}
public new void Dispose(){
}
}

public class test{//测试类
[STAThread]
static void Main(string[] args) {
MyControl ctl = new MyControl();
ctl.Dispose();
}
}
}

我想这种实现方式应该是微软的对现在这几个类的实现方式比较准确的模拟(抛开其他的继承类),
上面的MyControl类我继承了IDisposable接口并在MControl里面显式实现了该接口的方法,同时使用new关键字覆盖了父类Component的方法Dispose()。
这种实现是允许的但是在测试类里面IDisposable的实现是不会被执行的。
所以你在继承Control的时候只要覆盖父类的方法在子类的方法里面显式调用基类的方法就可以了,就向下面:
public class MyControl:Control,IDisposable{
public new void Dispose(){
base.Dispose();
}
}

不知道上面我说的那一句错了???被你认为是“对派生继承等概念还不是很清楚”,请你说清楚好吗?这样我也可以尽快的改正!

同时我想说那不是你的观点,那是面向对象的观点。对你举的例子我也认为有些“问题”。
Firestone2003 2004-09-04
  • 打赏
  • 举报
回复
呵呵
仔细看看文档
cuike519 2004-09-04
  • 打赏
  • 举报
回复
直接继承Control不用你重写该方法,所以微软在实现的时候应该使用的是new或者没有声明为可重裁的函数,如果你需要显式实现这个接口可以将你的控件再继承IDisposable接口,这样你可以显示的实现该接口。

dxj2000yt(桃李者):文档连接是有问题,但是你可能犯了一个错误,你仔细看看你在点击Control里面的Dispose以后,链接指的是ms-help://MS.MSDNQTR.2003FEB.1033/cpref/html/frlrfsystemcomponentmodelcomponentclassdisposetopic.htm这里,这个连接是Component类的是一个描述,你再看看该页的标题,说明该页是描述Component类的Dispose方法而不是Control的方法,为什么不能重裁因为Control没有将该方法声明为virtual的。

:-(
dxj2000yt 2004-09-04
  • 打赏
  • 举报
回复
to sanall:
你看看关于Dispose()的声明。
你说对了一般,应该重载void Dispose(bool dipsosing),
但是文档对Dispose()的声明,显示理论上我也可重载他!!!
Tooler 2004-09-04
  • 打赏
  • 举报
回复
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}
yingshis 2004-09-04
  • 打赏
  • 举报
回复
up
sanall 2004-09-04
  • 打赏
  • 举报
回复
是你错了,重载的Dispose访问修饰符是protected而不是public,而且你只能重载基类的void Dispose(bool dipsosing)这个函数而不是Dispose(),
leisang 2004-09-04
  • 打赏
  • 举报
回复
首先IDispose是个接口,所以要继承这个接口:
public class CRole:IDisposable

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(true);
}

protected virtual void Dispose(bool disposing)
{
if (! disposing)
return;

if (dsCommand != null )
{
if (dsCommand.SelectCommand != null)
{
if( dsCommand.SelectCommand.Connection != null)
dsCommand.SelectCommand.Connection.Dispose();
dsCommand.SelectCommand.Dispose();
}
dsCommand.Dispose();
dsCommand = null;
}
}
realljx 2004-09-04
  • 打赏
  • 举报
回复
关注/
dxj2000yt 2004-09-04
  • 打赏
  • 举报
回复
说这是特例说不过去,我宁愿认为这是BUG.
我以前说过一句话:不要轻易怀疑微软。看样子要打破这句谶言了。
下面是我的测试代码(完全通过),以证明我前面的观点:

--------------------------------------------
using System;

//-------------------------------------------------Class Manager
//parent class
abstract class Manager
{
//Method:KickOut
abstract public void KickOut();
};

abstract class AllManager:Manager
{
};

//sonclass1:FemaleManager
class FemaleManager:AllManager
{
override public void KickOut()
{
Console.WriteLine("Please Go Out!");
}
};
//sonclass2:MaleManager
class MaleManager:AllManager
{
override public void KickOut()
{
Console.WriteLine("Out!Shit!");
}
};

class ChatRoom
{
//manager to keep the room silent:Field
private Manager chatroommanager;

//property
public Manager ChatRoomManager
{
set{ chatroommanager=value; }
}

//Method
public void KickOut()
{
chatroommanager.KickOut();
}
};

//-------------------------------------------------TestApp
class TestApp
{
public static void Main(string []args)
{
ChatRoom chatroom = new ChatRoom();

chatroom.ChatRoomManager=new FemaleManager();
chatroom.KickOut();

chatroom.ChatRoomManager=new MaleManager();
chatroom.KickOut();

while(true);
}
};
gaobud 2004-09-04
  • 打赏
  • 举报
回复

重载只是在一个类中,重载与在继承的时候重写(override)没有关系,不会因为重载导至一个虚函数版本变成不是虚函数,虚函数不论override多少次他始终是虚函数,对于他所有的派生类虚函数都是虚函数,不论他的派生类有没有一个override版本,直到派生类使用了new 关键字隐藏了基类的虚函数版本


Dispose()虽然是虚函数() 但是C#编译器不允许重写基类的 Dispose() 可以把他看成是虚函数在基类中的一个特例--其目的是为了培养一个良好的编程习惯
Dispose()
{
GC.SuppressFinalize(this)
Dispose(true)
}
Dispose(Boolean)不但要在显示调用Dispose()的时候执行而且需要在垃圾收集的时候被动的执行
我们没必要去重写Dispose() 而且当重写Dispose(Boolean)
Firestone2003 2004-09-04
  • 打赏
  • 举报
回复
另外我不认为cuike519(marshal(修炼中))说的有错
是Dispose()在Component类中是virtual的
但是在Control中Dispose的定义是
protected override void Dispose(bool);
已经被重载了
所以Control的Dispose就不是Virtual的
dxj2000yt 2004-09-04
  • 打赏
  • 举报
回复
To cuike519(marshal(修炼中)):
不好意思,你说得我都看到了。
我认为你对派生继承等概念还不是很清楚。--原谅我直说(为了真理嘛!)
我的类派生自Control ,而Control派生自Component,因此我的类也就继承了Component类的成员。而Dispose()在Component类中是virtual的,因而我的类应该可以重载它!!!。
至少C++中这样是完全正确的,我以人头还有蒋介石的人格担保。

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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