我们先来看一下引用类型之间的转换,要注意引用类型之间的转换只存在于互相继承的类之间,不属于同一继承体系的类型是不能互相转换的。我们可以把子类对象实例可赋值给基类对象的行为认为是一种类型转换,这样说来子类对象可以隐式的转换为基类对象,抽象类或接口的实现类对象可以隐式转换为其相关的抽象类或接口对象,这就是引用类型所支持的隐式转换。引用类型的隐式转换和值类型的强制转换非常像,都会造成数据的丢失,这种数据丢失现象我们称为“切片”,即在转换时多余的部分会被“切”掉。比如一个浮点型要转换为整型,那么小数点后会被“切”掉,而一个子类对象转换为一个基类对象时,子类自身的数据和方法也会被“切”掉,基类对象只能调用子类继承它的那部分成员。我们来看一个例子,在这个例子中我们定义了基类A和其子类AB:
using System;
namespace Test
{
class A
{
public string a;
public void ShowA() { Console.WriteLine("A"); }
}
class AB :A
{
public string ab;
public void ShowAB()
{
Console.WriteLine("AB");
}
}
class Test
{
[STAThread]
static void Main(string [] args)
{
AB ab=new AB();
ab.ShowA();
ab.ShowAB();
//隐式转换,ab被转换为A类型
A a=ab;
a.ShowA();
}
}
}
运行后我们将ab转换为A类型,你会发现此时的a对象只能调用属于ab的ShowA方法,其他属于子类AB的字段和方法都被“切”掉,只保留AB继承自A类的方法和成员。上面的例子中A为普通类,实际上A为抽象类时也满足这个规律。当然,这只是一种表面的规律,至于内在的原因我们在前面已经介绍过,但你采用现在这种方式来考虑子类和基类的关系比较好操作一些。
基类对象向子类对象转换使用“(子类类型)”来完成,如下面代码:
class Test
{
[STAThread]
static void Main(string [] args)
{
A a1=new AB();
AB t1=(AB)a1; //正确
A a2=new A();
AB t2=(AB)a2; //不正确,将引发异常
t2.ShowAB();
}
}
上面的代码中,第一种强制转换是正确的,而第二种转换是错误的,所以在进行引用类型的强制转换时你需要确保基类对象本身引用的是子类对象方可将其转换为对应的子类对象。这样是不是很麻烦,考虑一下这种转换像是蛋生鸡鸡生蛋,还是像孙悟空变旗杆?我认为更像孙悟空变旗杆,不是所有的旗杆都会变回孙悟空,只有孙悟空变的那支才可以,这里的孙悟空就像子类对象,旗杆就像基类对象,这是在进行基类对象向子类对象转换时应该注意的问题。在介绍引用类型和值类型互相转换之前,我们需要先介绍一个重要的类——Object。在C#中,object类是一个极其重要的类,所有的类型,不管是值类型还是引用类型都隐式继承自该类。也就是说,对于C#中任何值类型变量或者引用类型对象都可以使用object类提供的方法。下面列出了object类包含的所有可用方法,并不多:
Equals:判断两个对象或变量是否相等,返回true为相等。
GetHashCode:产生一个哈希码,用于特定目的的哈希算法中。
GetType:获取当前实例的类型,返回Type对象。
ReferenceEquals:确定指定的object对象是否引用了相同实例。
ToString:返回当前对象或变量的文本值,如果没有文本值返回该对象类型名称。
我们先来看一下引用类型之间的转换,要注意引用类型之间的转换只存在于互相继承的类之间,不属于同一继承体系的类型是不能互相转换的。我们可以把子类对象实例可赋值给基类对象的行为认为是一种类型转换,这样说来子类对象可以隐式的转换为基类对象,抽象类或接口的实现类对象可以隐式转换为其相关的抽象类或接口对象,这就是引用类型所支持的隐式转换。引用类型的隐式转换和值类型的强制转换非常像,都会造成数据的丢失,这种数据丢失现象我们称为“切片”,即在转换时多余的部分会被“切”掉。比如一个浮点型要转换为整型,那么小数点后会被“切”掉,而一个子类对象转换为一个基类对象时,子类自身的数据和方法也会被“切”掉,基类对象只能调用子类继承它的那部分成员。我们来看一个例子,在这个例子中我们定义了基类A和其子类AB:
using System;
namespace Test
{
class A
{
public string a;
public void ShowA() { Console.WriteLine("A"); }
}
class AB :A
{
public string ab;
public void ShowAB()
{
Console.WriteLine("AB");
}
}
class Test
{
[STAThread]
static void Main(string [] args)
{
AB ab=new AB();
ab.ShowA();
ab.ShowAB();
//隐式转换,ab被转换为A类型
A a=ab;
a.ShowA();
}
}
}
运行后我们将ab转换为A类型,你会发现此时的a对象只能调用属于ab的ShowA方法,其他属于子类AB的字段和方法都被“切”掉,只保留AB继承自A类的方法和成员。上面的例子中A为普通类,实际上A为抽象类时也满足这个规律。当然,这只是一种表面的规律,至于内在的原因我们在前面已经介绍过,但你采用现在这种方式来考虑子类和基类的关系比较好操作一些。
基类对象向子类对象转换使用“(子类类型)”来完成,如下面代码:
class Test
{
[STAThread]
static void Main(string [] args)
{
A a1=new AB();
AB t1=(AB)a1; //正确
A a2=new A();
AB t2=(AB)a2; //不正确,将引发异常
t2.ShowAB();
}
}
上面的代码中,第一种强制转换是正确的,而第二种转换是错误的,所以在进行引用类型的强制转换时你需要确保基类对象本身引用的是子类对象方可将其转换为对应的子类对象。这样是不是很麻烦,考虑一下这种转换像是蛋生鸡鸡生蛋,还是像孙悟空变旗杆?我认为更像孙悟空变旗杆,不是所有的旗杆都会变回孙悟空,只有孙悟空变的那支才可以,这里的孙悟空就像子类对象,旗杆就像基类对象,这是在进行基类对象向子类对象转换时应该注意的问题。在介绍引用类型和值类型互相转换之前,我们需要先介绍一个重要的类——Object。在C#中,object类是一个极其重要的类,所有的类型,不管是值类型还是引用类型都隐式继承自该类。也就是说,对于C#中任何值类型变量或者引用类型对象都可以使用object类提供的方法。下面列出了object类包含的所有可用方法,并不多:
Equals:判断两个对象或变量是否相等,返回true为相等。
GetHashCode:产生一个哈希码,用于特定目的的哈希算法中。
GetType:获取当前实例的类型,返回Type对象。
ReferenceEquals:确定指定的object对象是否引用了相同实例。
ToString:返回当前对象或变量的文本值,如果没有文本值返回该对象类型名称。
}
class AB :A
{
public string ab;
public void ShowAB()
{
Console.WriteLine("AB");
}
}
class Test
{
[STAThread]
static void Main(string [] args)
{
AB ab=new AB();
ab.ShowA();
ab.ShowAB();
//隐式转换,ab被转换为A类型
A a=ab;
a.ShowA();
}
}
}
运行后我们将ab转换为A类型,你会发现此时的a对象只能调用属于ab的ShowA方法,其他属于子类AB的字段和方法都被“切”掉,只保留AB继承自A类的方法和成员。上面的例子中A为普通类,实际上A为抽象类时也满足这个规律。当然,这只是一种表面的规律,至于内在的原因我们在前面已经介绍过,但你采用现在这种方式来考虑子类和基类的关系比较好操作一些。
基类对象向子类对象转换使用“(子类类型)”来完成,如下面代码:
class Test
{
[STAThread]
static void Main(string [] args)
{
A a1=new AB();
AB t1=(AB)a1; //正确
A a2=new A();
AB t2=(AB)a2; //不正确,将引发异常
t2.ShowAB();
}
}
上面的代码中,第一种强制转换是正确的,而第二种转换是错误的,所以在进行引用类型的强制转换时你需要确保基类对象本身引用的是子类对象方可将其转换为对应的子类对象。这样是不是很麻烦,考虑一下这种转换像是蛋生鸡鸡生蛋,还是像孙悟空变旗杆?我认为更像孙悟空变旗杆,不是所有的旗杆都会变回孙悟空,只有孙悟空变的那支才可以,这里的孙悟空就像子类对象,旗杆就像基类对象,这是在进行基类对象向子类对象转换时应该注意的问题。在介绍引用类型和值类型互相转换之前,我们需要先介绍一个重要的类——Object。在C#中,object类是一个极其重要的类,所有的类型,不管是值类型还是引用类型都隐式继承自该类。也就是说,对于C#中任何值类型变量或者引用类型对象都可以使用object类提供的方法。下面列出了object类包含的所有可用方法,并不多:
Equals:判断两个对象或变量是否相等,返回true为相等。
GetHashCode:产生一个哈希码,用于特定目的的哈希算法中。
GetType:获取当前实例的类型,返回Type对象。
ReferenceEquals:确定指定的object对象是否引用了相同实例。
ToString:返回当前对象或变量的文本值,如果没有文本值返回该对象类型名称。
我们先来看一下引用类型之间的转换,要注意引用类型之间的转换只存在于互相继承的类之间,不属于同一继承体系的类型是不能互相转换的。我们可以把子类对象实例可赋值给基类对象的行为认为是一种类型转换,这样说来子类对象可以隐式的转换为基类对象,抽象类或接口的实现类对象可以隐式转换为其相关的抽象类或接口对象,这就是引用类型所支持的隐式转换。引用类型的隐式转换和值类型的强制转换非常像,都会造成数据的丢失,这种数据丢失现象我们称为“切片”,即在转换时多余的部分会被“切”掉。比如一个浮点型要转换为整型,那么小数点后会被“切”掉,而一个子类对象转换为一个基类对象时,子类自身的数据和方法也会被“切”掉,基类对象只能调用子类继承它的那部分成员。我们来看一个例子,在这个例子中我们定义了基类A和其子类AB:
using System;
namespace Test
{
class A
{
public string a;
public void ShowA() { Console.WriteLine("A"); }
}
class AB :A
{
public string ab;
public void ShowAB()
{
Console.WriteLine("AB");
}
}
class Test
{
[STAThread]
static void Main(string [] args)
{
AB ab=new AB();
ab.ShowA();
ab.ShowAB();
//隐式转换,ab被转换为A类型
A a=ab;
a.ShowA();
}
}
}
运行后我们将ab转换为A类型,你会发现此时的a对象只能调用属于ab的ShowA方法,其他属于子类AB的字段和方法都被“切”掉,只保留AB继承自A类的方法和成员。上面的例子中A为普通类,实际上A为抽象类时也满足这个规律。当然,这只是一种表面的规律,至于内在的原因我们在前面已经介绍过,但你采用现在这种方式来考虑子类和基类的关系比较好操作一些。
基类对象向子类对象转换使用“(子类类型)”来完成,如下面代码:
class Test
{
[STAThread]
static void Main(string [] args)
{
A a1=new AB();
AB t1=(AB)a1; //正确
A a2=new A();
AB t2=(AB)a2; //不正确,将引发异常
t2.ShowAB();
}
}
上面的代码中,第一种强制转换是正确的,而第二种转换是错误的,所以在进行引用类型的强制转换时你需要确保基类对象本身引用的是子类对象方可将其转换为对应的子类对象。这样是不是很麻烦,考虑一下这种转换像是蛋生鸡鸡生蛋,还是像孙悟空变旗杆?我认为更像孙悟空变旗杆,不是所有的旗杆都会变回孙悟空,只有孙悟空变的那支才可以,这里的孙悟空就像子类对象,旗杆就像基类对象,这是在进行基类对象向子类对象转换时应该注意的问题。在介绍引用类型和值类型互相转换之前,我们需要先介绍一个重要的类——Object。在C#中,object类是一个极其重要的类,所有的类型,不管是值类型还是引用类型都隐式继承自该类。也就是说,对于C#中任何值类型变量或者引用类型对象都可以使用object类提供的方法。下面列出了object类包含的所有可用方法,并不多:
Equals:判断两个对象或变量是否相等,返回true为相等。
GetHashCode:产生一个哈希码,用于特定目的的哈希算法中。
GetType:获取当前实例的类型,返回Type对象。
ReferenceEquals:确定指定的object对象是否引用了相同实例。
ToString:返回当前对象或变量的文本值,如果没有文本值返回该对象类型名称。