看这篇文章之前先看一下MSDN中的解释,毕竟人家是最权威的。
MSDN:this 关键字引用类的当前实例。
便于大家理解下面我说的话,咱们还是以例子来说明问题。
public class Class1
{
public void Disp()
{
string str=this.GetType().Name;
}
}
上面我定义了一个简单的不能再简单的类。如果我实例化一个Class1类,然后用这个对象去调用Disp方法,这里的str肯定是字符串Class1。这是没有任何悬念的,也符合MSDN中的解释。
Class1 c1=new Class1();
c1.Disp();//这个时候方法中的str的值是字符串Class1。
下面接着看,饭得一口口的吃,吃多了容易撑死,所以咱也得慢慢的讲。
再定义一个Class2类继承自Class1类,如下:
public class Class2:Class1
{
}
这个类中什么都没有,这个时候用这样的方式去调用Disp方法。
Class2 c2=new Class2();
c2.Disp();
由于Class2继承自Class1,所以c2会调用父类中的Disp方法。这个时候Disp方法中的str的值是多少呢?结果是字符串Class2。为什么呢?这好像不太符合微软MSDN的说法,或者我们之前对this的理解有误区。
那下面我是否可以这样做定论呢?this的类型不取决于它所在的类,而是调用它的实例。也就是说能调用Disp方法的除了定义它的类之外还有它的子类。所以this的类型取决于调用它的实例。
但是,下面接着看。
修改上面的例子,在Class1与Class2中都定义一个属性GetStr,类Class1中的属性返回字符串Class1,类Class2中的GetStr属性返回字符串Class2。如下:
public class Class1
{
public string GetStr
{
get
{
return "Class1";
}
}
public void Disp()
{
string str=this.GetType().Name; //结果为Class2
string str2 = this.GetStr;//结果为Class1
}
}
public class Class2:Class1
{
public new string GetStr
{
get
{
return "Class2";
}
}
}
还是使用下面的方式进行调用,如下:
Class2 c2=new Class2();
c2.Disp();
这个时候Class1类中的Disp方法中的this.GetType().Name的值是Class2,这说明this的类型Class2,也就是说this此时引用的是类Class2的实例。但这时矛盾就出来了,通过this去调用GetStr属性的时候,它返回的是Class1,而不是Class2。此时的this既然是Class2的一个实例,可为什么调用的不是Class2中定义的GetStr属性呢?为什么呢?我现在也不能解释,只能说通过this调用的方法、属性或字段,它调用的时候都是this所在的那个类中定义的方法、属性或字段,而不管他的类型是什么。
MSDN:this 关键字引用类的当前实例。
便于大家理解下面我说的话,咱们还是以例子来说明问题。
public class Class1
{
public void Disp()
{
string str=this.GetType().Name;
}
}
上面我定义了一个简单的不能再简单的类。如果我实例化一个Class1类,然后用这个对象去调用Disp方法,这里的str肯定是字符串Class1。这是没有任何悬念的,也符合MSDN中的解释。
Class1 c1=new Class1();
c1.Disp();//这个时候方法中的str的值是字符串Class1。
下面接着看,饭得一口口的吃,吃多了容易撑死,所以咱也得慢慢的讲。
再定义一个Class2类继承自Class1类,如下:
public class Class2:Class1
{
}
这个类中什么都没有,这个时候用这样的方式去调用Disp方法。
Class2 c2=new Class2();
c2.Disp();
由于Class2继承自Class1,所以c2会调用父类中的Disp方法。这个时候Disp方法中的str的值是多少呢?结果是字符串Class2。为什么呢?这好像不太符合微软MSDN的说法,或者我们之前对this的理解有误区。
那下面我是否可以这样做定论呢?this的类型不取决于它所在的类,而是调用它的实例。也就是说能调用Disp方法的除了定义它的类之外还有它的子类。所以this的类型取决于调用它的实例。
但是,下面接着看。
修改上面的例子,在Class1与Class2中都定义一个属性GetStr,类Class1中的属性返回字符串Class1,类Class2中的GetStr属性返回字符串Class2。如下:
public class Class1
{
public string GetStr
{
get
{
return "Class1";
}
}
public void Disp()
{
string str=this.GetType().Name; //结果为Class2
string str2 = this.GetStr;//结果为Class1
}
}
public class Class2:Class1
{
public new string GetStr
{
get
{
return "Class2";
}
}
}
还是使用下面的方式进行调用,如下:
Class2 c2=new Class2();
c2.Disp();
这个时候Class1类中的Disp方法中的this.GetType().Name的值是Class2,这说明this的类型Class2,也就是说this此时引用的是类Class2的实例。但这时矛盾就出来了,通过this去调用GetStr属性的时候,它返回的是Class1,而不是Class2。此时的this既然是Class2的一个实例,可为什么调用的不是Class2中定义的GetStr属性呢?为什么呢?我现在也不能解释,只能说通过this调用的方法、属性或字段,它调用的时候都是this所在的那个类中定义的方法、属性或字段,而不管他的类型是什么。
解决方案 »
- C# ComboBox DroppedDown属性存在的问题
- VS 2008 自动关闭问题
- c#怎么控制摄像头?我想写个间隔指定时间连续拍照的
- 困惑了我N天了还没解决!winform请问长操作时如何弹出窗口,等长操作完成后自动关闭???
- aspos.chart图表控件x轴怎么定义为月份
- 我想問一下我想在后台代碼里寫Repeater.Itemtemplate這個屬性,行嗎?
- 谁能帮我推荐基本C#-设计模式的书和C#高级编程的书?谢谢
- 關於註冊系統熱鍵的問題
- WCF开发 自动检测新版本,更新客户端。该怎么解决
- 使用MessageBox.Show()应该添加什么using?
- 关于notifyicon
- 如何通过代码修改web.Config?
他的实现可能要追溯到根源
但是GETSTR是CLASS1独有的方法这样,我的设想是,在GETTYPE的时候,底层的实现可能是用某种机制获取了当前实例的类型
也就是说,CLASS2的调用GETTYPE的时候,按照CLASS2 → CLASS1 → OBJECT的方向来调用的
但是到了GETSTR就变成了,CLASS2 → CLASS1,直接就到底了
所以引起了这样的结果
但是,GETSTR调用的是CLASS1的GETSTR
之所以this.GetStr是class1,因为你的class2的getstr是重写的,是没有继承关系的,它就自然是去调用class1的
这不是this的问题吧
这样的话就都是class2了: public class Class1
{
public virtual string GetStr
{
get
{
return "Class1";
}
}
public void Disp()
{
string str = this.GetType().Name; //结果为Class2
string str2 = this.GetStr;//结果为Class2
}
}
public class Class2 : Class1
{
public override string GetStr
{
get
{
return "Class2";
}
}
}
到底是谁没看懂?
lz的DISP中调用的是CLASS1的GETSTR 那是当然的,结果lz都给出了
lz是想问 string str2 = this.GetStr; 中既然this是class2的实例,但为何却在调用class1的getstr属性而不是调用this代表的class2的getstr
你的回答根本不解决lz的问题但是到了GETSTR就变成了,CLASS2 → CLASS1,直接就到底了
什么叫直接就到底了?
我试了一下你的代码确实是这样的,但我还是搞不懂,通过new来重新定义的一个属性 他怎么就不能通过this来访问的呢?
如果不是在Class1中的方法中调用的话 通过正常情况Class2 c2=new Class2()声明一个Class2实例c2 c2就可以调用这个新属性期待中。。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication49
{
public partial class Form1 : Form
{
public class Class1
{
public string GetStr
{
get
{
return "Class1";
}
}
public void Disp()
{
string str = this.GetType().Name; //结果为Class2
string str2 = this.GetStr;//结果为Class1 bool Flag = this is Class2; // 判定当前的this 是不是 class2类型的,返回true ,说明是判定为class2的
// 在这里设置断点监视查看this的值,也会发现this的值是class2
Class2 C2 = (Class2)this; // 但无法直接赋给一个class2变量,
// 会提示class1转class2需要一个强制转换"
// 无法将类型“WindowsApplication49.Form1.Class1”
// 隐式转换为“WindowsApplication49.Form1.Class2”。存在一个显式转换(是否缺少强制转换?)
string s = C2.GetStr; // class2 // 总结:CLR里这种情况下,在class1内部,this代表着class1,但类型相关的信息还是new时的class2而没有同步更新过,
// 所以这里取this.GetType().Name是不准确的,不知道算不算是CLR的一个小bug
}
}
public class Class2 : Class1
{
public new string GetStr // 重写,非继承
{
get
{
return "Class2";
}
}
} public Form1()
{
Class2 c2 = new Class2();
c2.Disp();
string s = c2.GetStr; // class2
}
}
}
this.GetType()相当于Type.GetTypeFromHandle(Type.GetTypeHandle(this))或者Type.GetTypeArray(new object[] {this})[0]
public class Class1
{
public string GetStr
{
get
{
return "Class1";
}
}
public void Disp()
{
string str=this.GetType().Name; //结果为Class2
string str2 = this.GetStr;//结果为Class1
}
}
public class Class2:Class1
{
public new string GetStr
{
get
{
return "Class2";
}
}
} 当你用c2.Disp()的时候,this始终代表c2,
为什么会出现上面的问题呢
很简单,编译的时候根本不知道Disp会被Class1或是Class2调用,
所以this编译时类型是Class1,运行的时候this的运行时类型就是Class2了,
此时调用this.GetType,GetType从Object继承,所以会去调用Object.GetType,这个方法的作用是打印类型信息,所以打出来是Class2
调用this.Disp(),因为Disp不是virtual,所以不存在被Class2重写的可能,所以直接调用Class1的,所以输出Class1如果,Disp定义成virtual,则运行时会检查Class2是否override了Disp,如果有则调用Class2的Disp,否则还是调用Class1的Disp由此可知,若要实现多态,应使用virtual和override