代码改变世界

类型转换

2009-04-11 22:03  K-imba  阅读(896)  评论(0编辑  收藏  举报
 类型转换 
    显示转换
    隐式转换
    用户自定义转换

(1)   
隐式转换:一般是低类型向高类型转化,能够保证值不发生变化。
        隐式数值转换: 
         sbyte 到 short、int、long、float、double 或 decimal。 
         byte 到 short、ushort、int、uint、long、ulong、float double 或 decimal。
         short 到 int、long、float、double 或 decimal。
         ushort 到 int、uint、long、ulong、float、double 或 decimal。 
         int 到 long、float、double 或 decimal。 
         uint 到 long、ulong、float、double 或 decimal。
         long 到 float、double 或 decimal。 
         ulong 到 float、double 或 decimal。
         char 到 ushort、int、uint、long、ulong、float、double 或 decimal。 
         float 到 double。 
        不存在向 char 类型的隐式转换,因此其它整型的值不会自动转换为 char 类型。
        浮点型不能隐式地转化为decimal型

       隐式枚举转换   
          
隐式枚举转换允许将十进制整数 0 转换为任何枚举类型。

      隐式引用转换
              派生类向基类转换
              隐式引用转换是指一类引用类型之间的转换,这种转换总是可以成功,因此不需要在运行时进行任何检查。

       装箱转换
              装箱转换允许将值类型隐式转换为引用类型。

(2)    显示转换:也称强制类型转换。不能保证数据的正确性。
      (type)(表达式)

(3) 用户自定义转换
       所有的用户自定义转换都是静态的,要使用static关键字
       用户自定义转换分显示和隐示,它们用implicit(隐式转换)或 explicit(显示转换)关键字声明。
       static 访问修辞符 转换修辞符 operator 转换类型(参数)

示例:

using System;
struct Number
{
       private int value;
       public Number(int value) 
      
              this.value = value; 
       }
       //用户自定义整型到Number型的隐式转换
       static public implicit operator Number(int value) 
       {
              return new Number(value);
       }
       // 用户自定义从Number型到整型的显示转换
       static public explicit operator int(Number n)
       {
              return n.value;
       }
       //用户自定义从Number类型到string类型的隐式转换
       static public implicit operator string(Number n)
       {
              return n.ToString();
       }
}

class Test
{
      static public void Main()
       {
              Number n;
              n= 10;     
              Console.WriteLine((int)n);
              //隐式转换到string
              Console.WriteLine(n);   
      }
} 

使用System.Convert

       将一个基本数据类型转换为另一个基本数据类型。

使用Parse方法

大部份预定义值类型都有这个静态方法,用来将相应的文本转化为相应的值类型。

装箱和取消装箱

       装箱取消装箱使值类型能够与 object 类型相互转换。

       装箱转换允许将值类型隐式转换为引用类型。将值类型的值装箱的操作包括:分配一个对象实例值类型的值复制到该实例中

示例:

       此例将整数变量 i 通过装箱转换为对象 o。此例显示对象保留了内容的原始副本,即 123

using System;
class TestBoxing 
{
   public static void Main() 
   {
      int i = 123;
      object o = i;  // 隐式的装箱
      i = 456;       // 改变变量i的值
      Console.WriteLine("The value-type value = {0}", i);       //456
      Console.WriteLine("The object-type value = {0}", o);     //123 i的复制值
   }
}
       取消装箱转换:取消装箱转换允许将引用类型显式转换为值类型。

       取消装箱操作包括以下两个步骤:首先检查该对象实例是否是某个给定的值类型的装了箱的值,然后将值从实例中复制出来。
示例:

       下面的示例阐释无效取消装箱的情况,即错误的取消装箱如何导致 InvalidCastException。通过使用 try catch,发生错误时会显示错误信息。
using System;
public class UnboxingTest
{
   public static void Main() 
   {
      int intI = 123;
      object o = intI; //装箱
      try 
      {
         int intJ = (short) o; //取消装箱无效,short不是装了箱的值类型. 检查该对象实例是否是某个给定的值类型的装了箱的值
         Console.WriteLine("Unboxing OK.");
      }
      catch (InvalidCastException e) 
      {
         Console.WriteLine("{0} Error: Incorrect unboxing.",e);
      }
   }
} 

其它转换用运算符
as

as 运算符用于执行引用类型的显式类型转换。 如果要转换的类型与指定类型兼容,转换就会成功;如果类型不兼容,则返回null
       表达式as 类型
as 运算符类似于类型转换,所不同的是,当转换失败时,as 运算符将返回null,而不是引发异常。
示例:
       object o1=”SomeString”;
       object o2=5;
       string s1=o1 as string;  //类型兼容 s1=”SomeString”
       string s2=o2 as string;  //s2=null

is

is 运算符用于检查对象的类型是否与给定类型兼容(对象是该类型,或是派生于该类型)
       表达式 is 类型
示例:
       int i=10;
       if ( i is object) //true
       {}

sizeof

sizeof 运算符用于获得值类型的大小(以字节为单位)。
       sizeof(type)
sizeof 运算符仅适用于值类型,而不适用于引用类型。
sizeof 运算符仅可用于 unsafe 模式。
示例:
       unsafe
       {
              Console.WriteLine(“{0}”,sizeof(int));
       } 

posted on 2005-12-30 14:34 小飞侠 阅读(2187) 评论(2)  编辑 收藏 网摘 所属分类: C#入门知识

本教程参考C#和ASP.NET程序设计教程撰写,有什么不足之处请大家指出,或在老猫的理想BLOG留言。

这次我们首先讲解一下类型转换,我们在写程序时经常用到类型转换,而且特别多的规则。我在这里粗略的讲解一下。
隐式转换是系统默认的、不需要加以声明即可进行的转换。
1.隐式数值转换
隐式数值转换实际上就是从低精度的数值类型转换到高精度的数值类型的转换。 byte x=255;ushort y=x;y=65535;float z=y;//均从低精度到高精度,反之会产生溢出隐式数值转换的类型太多,我就不多介绍,记住上面的原则就可以了。详细规则可查看msdn
2.隐式枚举转换
隐式枚举转换用于把十进制整数0转换成任何枚举类型,对应的其他整数则不存在这种转换。 using System;
enum Color
{
    Red,Green,Blue
};
class MikeCat
{
     static void Main()
     {
          Color c;//声明Color的变量c;
          c=0;//将0转换为Red;
          Console.WriteLine("c的值是{0}",c);//结果:c的值是Red;如果将c=0改成c=1,则编译器会给出错误。
      }
} 3.隐式引用转换
从任何引用类型到object的转换。
从类类型A到类类型B的转换,其中类A从类B派生得到。
从类类型A到接口类型B的转换,其中类A实现了接口B。
从接口类型A到接口类型B的转换,其中接口A是从接口B派生。
从任何数组类型到System.Array的转换。
从任何委托类型到System.Delegate的转换。
从任何数组类型或委托类型到System.ICloneable的转换。
从空类型(null)到任何引用类型的转换。
显示转换也称为强制转换,它需要用户明确地指定转换的类型。 char c=(char)65;//A
int i=(int)'A';//65 显示转换包含所有的隐式转换,即任何系统允许的隐式转换写成显示转换的形式都是允许的。 int i=300;
long l=(long)i; 另外一例:  using System;
class MikeCat
{
     static void Main() 
     {
          long longValue = Int64.MaxValue;
          int intValue = (int) longValue;
          Console.WriteLine("(int){0} = {1}", longValue, intValue);
      }
} 类型 long 转换为 int 是显式转换,它使用了强制转换表达式。输出为:
            (int) 9223372036854775807 = -1这是因为有溢出发生。
1.显示数值转换
显示数值转换是指当不存在相应的隐式转换时从一种数值类型转换为另一种数值类型。转换类型也很繁琐,只需记住转换规则,详细查阅MSDN。由于显示数值转换可能丢失信息或引发异常,因此转换按以下原理被处理:简略说就是高精度显示转换为低精度会引发异常(OverFlowException),未引发异常的情况,源变量的值通过舍入得到最接近的整型值作为转换结果。详细转换时的异常情况查阅MSDN /*test.cs*/
using System;
public class MikeCat
{
   public static void Main()
   {
       ushort u=65535;
       byte b=(byte)u;
       Console.WriteLine("b的值是{0}",b);
   }
} 编译状况如下:
                     E:\>csc test.cs
                    Microsoft (R) Visual C# .NET 编译器版本 7.10.3052.4
                    用于 Microsoft (R) .NET Framework 版本 1.1.4322
                    版权所有 (C) Microsoft Corporation 2001-2002。保留所有权利。
                    E:\>test.exe
                    b的值是255
                    E:\>csc/checked test.cs ///checked[+|-] 生成溢出检查
                    E:\>test.exe
                    未处理的异常: System.OverflowException: 算术运算导致溢出。
                    at MikeCat.Main()
                    E:\>csc/checked- test.cs
                    E:\>test.exe
                    b的值是255
2.显示枚举转换
显示枚举转换其实就是将枚举类型的元素类型与相应类型之间进行隐式显示转换。比如,有一个元素类型int的枚举类型E,当执行从E到byte的显示枚举转换时,实际执行的是从int到byte的显示数值转换。 using System;
enum Color
{
    Red,Green,Blue
};
public class MikeCat
{
      static void Main()
      {
           Color c;//声明Color的变量c;
           c=(Color)4;//对数字3进行显示枚举转换
           Console.WriteLine("c的值是{0}",c);
      }
} 结果:c的值是4
Convert 类
将一个基本数据类型转换为另一个基本数据类型。
该类返回值与指定类型的值等效的类型。受支持的基类型是 Boolean、Char、SByte、Byte、Int16、Int32、Int64、UInt16、UInt32、UInt64、Single、 Double、Decimal、DateTime 和 String。

存在将每个基类型转换为每个其他基类型的转换方法。不过,所执行的实际转换操作分为三类:

从某类型到它本身的转换只返回该类型。不实际执行任何转换。
无法产生有意义的结果的转换引发 InvalidCastException。不实际执行任何转换。下列转换会引发异常:从 Char 转换为 Boolean、Single、Double、Decimal 或 DateTime,以及从这些类型转换为 Char。下列转换会引发异常:从 DateTime 转换为除 String 之外的任何类型,以及从任何类型(String 除外)转换为 DateTime。
任何基类型(上面描述的基类型除外)都可以与任何其他基类型进行相互转换。
如果数字类型转换导致精度丢失(即某些最低有效位丢失),不引发异常。但是,如果结果超出了特定转换方法的返回值类型所能表示的范围,则将引发异常。

下面介绍一下和类型转换相关的装箱、取消装箱
装箱是值类型到 object 类型或到该值类型所实现的任何接口类型的隐式转换。将一个值的值装箱会分配一个对象实例并将该值复制到新的对象中。

请看以下值类型变量的声明:
       int i = 123; 以下语句对变量 i 隐式应用装箱操作:
       object o = i;
此语句的结果是在堆栈上创建对象 o,而该对象在堆上引用 int 类型的值。该值是赋给变量 i 的值类型值的一个副本。下图说明了两个变量 i 和 o 之间的差异。

        装箱转换
        在堆栈上            在堆上
        i 123
        int i=123;
        o                    (将i装箱)
        object o=i;            int 123
        也可以(但绝不必要)如下例所示显式执行装箱:
        int i = 123;
        object o = (object) i;
示例
此例将整数变量 i 通过装箱转换为对象 o。这样,存储在变量 i 中的值就从 123 更改为 456。此例显示对象保留了内容的原始副本,即 123。   // boxing.cs
// Boxing an integer variable
using System;
class TestBoxing 
{
    public static void Main() 
    {
        int i = 123;
        object o = i; // Implicit boxing
        i = 456; // Change the contents of i
        Console.WriteLine("The value-type value = {0}", i);
        Console.WriteLine("The object-type value = {0}", o);
    }
} 输出
        The value-type value = 456
        The object-type value = 123

取消装箱
取消装箱是从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。取消装箱操作包括:

检查对象实例,确保它是给定值类型的一个装箱值。 
将该值从实例复制到值类型变量中。
以下语句同时说明了装箱和取消装箱操作:

int i = 123; // A value type
object box = i; // Boxing
int j = (int)box; // Unboxing 下图显示了以上语句的结果。

取消装箱转换
        在堆栈上        在堆上
        i 123
        int i=123;
        o                (将i装箱)
        object o=i;        int 123
        j 123
        int j=(int) o;
为使到给定值类型的取消装箱转换在运行时取得成功,源参数的值必须是对某个对象的引用,而该对象先前是通过将该值类型的值装箱创建的。如果源参数为 null 或是对一个不兼容对象的引用,则会引发 InvalidCastException。
示例
下面的示例阐释无效取消装箱的情况,即错误的取消装箱如何导致 InvalidCastException。通过使用 try 和 catch,发生错误时会显示错误信息。
      using System;
public class UnboxingTest
{
    public static void Main() 
    {
        int intI = 123;
        // Boxing
        object o = intI;
        // Reference to incompatible object produces InvalidCastException
        try 
        {
            int intJ = (short) o;
            Console.WriteLine("Unboxing OK.");
        }
        catch (InvalidCastException e) 
        {
            Console.WriteLine("{0} Error: Incorrect unboxing.",e);
        }
    }
}         输出
        System.InvalidCastException
         at UnboxingTest.Main() Error: Incorrect unboxing.
        如果将下列语句:
        int intJ = (short) o;
        更改为:
        int intJ = (int) o;
        转换将执行,而您将得到输出“Unboxing OK”。