这里的this.Fun1();其中的this到底是基类的对象还是派生类的对象。

微创社(MCC) 2009-08-11 10:38:21
原问题是yzx_224提出来的,
原始的贴子见下:
http://topic.csdn.net/u/20090805/22/5e0c911d-eb09-41d9-8878-3d4762e102cf.html#replyachor

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestVitual
{
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
Console.WriteLine("@@@");
DerivedClass dc = new DerivedClass();
}
}

class BaseClass
{
public BaseClass()
{
Console.WriteLine("Base Constructor");
this.Fun1();//稍改了一下原码,增加了这个this
}
public virtual void Fun1()
{
Console.WriteLine("Base Fun1");
}
public void Fun2(BaseClass dc)
{
dc.Fun1();
Fun1();
}
}

class DerivedClass: BaseClass
{
public DerivedClass()
{
Console.WriteLine("Derived Constructor");
}
public override void Fun1()
{
Console.WriteLine("Derived Fun1");
}
}
}
执行结果如下:
Base Constructor
Base Fun1
@@@
Base Constructor
Derived Fun1
Derived Constructor
请按任意键继续. . .

问题来了:
在class BaseClass中的语句,this.Fun1();,这个this到底代表了哪个类的对象?
[1]sp1234认为:这个this不是什么“基类的对象”。
[2]pcnetman888认为:这个this正是“基类的对象”。

请问你支持哪个观点?
[1]还是[2],为什么?
...全文
245 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
xingjunli 2009-08-13
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 vrhero 的回复:]
...
所以,“在class BaseClass中的语句,this.Fun1();,这个this到底代表了哪个类的对象?”...答案是实例的对象,new哪个就是哪个的对象,与它写在哪个class中完全没有关系...
...
[/Quote]
this 是指向(new)实例对像的引用,同类不搭嘎
yzx_224 2009-08-12
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 vrhero 的回复:]
1.首先是为属性和字段分配存储空间,然后沿继承树读取基类BaseClass元数据并为其属性和字段分配存储空间,依次类推直到递归结束,也就是直到完成System.Object内存分配为止...如果基类和子类出现了同名属性或字段,编译器将认为这是两个不同的成员...你这两个类都没有属性和字段,可以忽略...

2.然后是关联方法列表...注意方法列表的创建是在类对象第一次加载到CLR时完成的,在创建实例对象时只是将其附加成员TypeHandle指向方法列表在Loader Heap上的地址,将对象与其动态方法列表关联,因此方法表是先于实例对象创建的...类对象DerivedClass创建方法表时首先将BaseClass的方法列表复制一份,然后和DerivedClass本身的方法列表进行比对,如果有覆写的虚方法则以子类方法覆盖同名的父类方法,最后添加子类的新方法...同样如果基类和子类出现了非覆写的同名方法,编译器将认为这是两个不同的成员...

BaseClass bc = new DerivedClass();
再来看看这句做了什么...声明一个BaseClass类型对象bc,创建一个新的DerivedClass实例对象将其引用赋值给bc...这也应该人人皆知...但是看了上面的解释,你是否明白了为什么说这里只创建了一个实例对象,没有什么BaseClass实例对象了吗?...还不明白就只有去认真看几天MSDN了...

所以,“在class BaseClass中的语句,this.Fun1();,这个this到底代表了哪个类的对象?”...答案是实例的对象,new哪个就是哪个的对象,与它写在哪个class中完全没有关系...
[/Quote]
vrhero的这段回复让我有了一点头绪,那个第1点和第2点从逻辑上讲完全正确,不过能不能给个验证方法或者事实依据(有点贪了,呵呵)?
LQknife 2009-08-12
  • 打赏
  • 举报
回复
那啥时oo的本质呢
xingjunli 2009-08-12
  • 打赏
  • 举报
回复
个人理解:this本身不能代表谁故不能用是正是等同于某个对像,this是一个指针指向引用类的当前实例(说白了就是你在哪个类里面用this他就指向哪个实例对像);使用this可以限定名称相似的成员,将对像作为参数传递到其它方法,申明索引器等(MSDN的解释)this 保留字不能用于静态成员的实现里,因为这时对象或结构并未实例化
  • 打赏
  • 举报
回复
this.Fun1();//稍改了一下原码,增加了这个this

DerivedClass dc = new DerivedClass();
this就是dc

dc的定义相当于:
class DerivedClass
{
public DerivedClass()
{
Console.WriteLine("Base Constructor");
this.Fun1();//稍改了一下原码,增加了这个this
Console.WriteLine("Derived Constructor");
}
public void Fun1()
{
Console.WriteLine("Derived Fun1");
}

public void Fun2(BaseClass dc)
{
dc.Fun1();
Fun1();
}
}
微创社(MCC) 2009-08-12
  • 打赏
  • 举报
回复
好拉,不打算买关了了。
看代码先:
using System;

class B
{
public virtual void TestIt(int val)
{
Console.WriteLine("TestIt by int:{0}", val);
}

}

class BB : B
{
public override void TestIt(int val)
{
Console.WriteLine("TestIt by int:{0}", val);
}
public void TestIt(double val)
{
Console.WriteLine("TestIt by double:{0}", val);
}
}

class Test
{
static void Main()
{
int val = 100;
BB a = new BB();
a.TestIt(val);//调用了谁?

Console.ReadKey();
}
}


这个案例,是为了证明,
多态的情况下,对象调用的发源地是哪里,
是基类,还是派生类...



至于LQknife所指的本质,还是在于多态发生的地点嘛,OO都是为多态服务的,你认为是否本质了~~

微创社(MCC) 2009-08-12
  • 打赏
  • 举报
回复
to:vrhero

我发现你的思维很独特,

总是能够“文不对题”
而且还能“涛涛不绝”

呵呵,一点浅见~~

请在理解别人的基础上,再发表意见好不好~~
vrhero 2009-08-12
  • 打赏
  • 举报
回复
[Quote=引用楼主 pcnetman888 的回复:]
问题来了:
在class BaseClass中的语句,this.Fun1();,这个this到底代表了哪个类的对象?
[1]sp1234认为:这个this不是什么“基类的对象”。
[2]pcnetman888认为:这个this正是“基类的对象”。
[/Quote]
说明你没有看懂原帖中这一句的上下文...你的错误在于将对象的实例化过程想当然地简单理解为几个实例对象的迭加...

DerivedClass的实例对象就是DerivedClass的实例对象,其内部不会存在一个BaseClass的实例对象...只不过这个对象可以转换为BaseClass类型对象...可以转换并不表示其转换后就变成了另一个实例对象,实例还是DerivedClass实例...

DerivedClass dc = new DerivedClass();
来看看这句做了什么...声明一个DerivedClass类型对象dc,创建一个新的DerivedClass实例对象将其引用赋值给dc...这个板块应该人人皆知,但是到底做了什么呢?

1.首先是为属性和字段分配存储空间,然后沿继承树读取基类BaseClass元数据并为其属性和字段分配存储空间,依次类推直到递归结束,也就是直到完成System.Object内存分配为止...如果基类和子类出现了同名属性或字段,编译器将认为这是两个不同的成员...你这两个类都没有属性和字段,可以忽略...

2.然后是关联方法列表...注意方法列表的创建是在类对象第一次加载到CLR时完成的,在创建实例对象时只是将其附加成员TypeHandle指向方法列表在Loader Heap上的地址,将对象与其动态方法列表关联,因此方法表是先于实例对象创建的...类对象DerivedClass创建方法表时首先将BaseClass的方法列表复制一份,然后和DerivedClass本身的方法列表进行比对,如果有覆写的虚方法则以子类方法覆盖同名的父类方法,最后添加子类的新方法...同样如果基类和子类出现了非覆写的同名方法,编译器将认为这是两个不同的成员...

BaseClass bc = new DerivedClass();
再来看看这句做了什么...声明一个BaseClass类型对象bc,创建一个新的DerivedClass实例对象将其引用赋值给bc...这也应该人人皆知...但是看了上面的解释,你是否明白了为什么说这里只创建了一个实例对象,没有什么BaseClass实例对象了吗?...还不明白就只有去认真看几天MSDN了...

所以,“在class BaseClass中的语句,this.Fun1();,这个this到底代表了哪个类的对象?”...答案是实例的对象,new哪个就是哪个的对象,与它写在哪个class中完全没有关系...

再次不厌其烦地重复sp1234、我和其他一些老家伙们经常挂在嘴边的一句话:不要把你在C++或其他什么语言中对继承、引用等等的“理解”直接硬套在.NET的相同词汇上(大致意思)...虽然它们概念也许相同,实现却可能是天差地别...
boringame 2009-08-12
  • 打赏
  • 举报
回复
this指向new的那个类,
在这里也就是子类。
微创社(MCC) 2009-08-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 ojlovecd 的回复:]
加断点调试一下不就知道了……
[/Quote]
给个答案了^_^

问题的本质,跟上面的代码没有太多的关系,
简单点说:就是"重写"(OVERRIDE)的方法,
调用的是写在“子类”里面的那段代码,这个没有问题,
问题是,这个方法是“子类”拥有的,还是“基类”拥有的?!

这个关系到:OO的本质。
yzx_224 2009-08-11
  • 打赏
  • 举报
回复
对了 sp1234给了一个方法 就是在基类构造函数里调用GetType(this)
yzx_224 2009-08-11
  • 打赏
  • 举报
回复
问题我引出来的
我一前几天看过运行时候this的类型
实例化那个类时就是谁的对象
所以就出现了我在
http://topic.csdn.net/u/20090807/09/28a33678-7d6a-427d-9988-b7dc7acc3822.html
这个帖子中说的情况……
微软不开源 这个问题很严肃啊……
我姓区不姓区 2009-08-11
  • 打赏
  • 举报
回复
加断点调试一下不就知道了……

110,544

社区成员

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

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

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