zoukankan      html  css  js  c++  java
  • C#高级编程四十一天----用户定义的数据类型转换

    用户定义的数据类型转换

    C#同意定义自己的 数据类型,这意味着须要某些 工具支持在自己的数据类型间进行数据转换.方法是把数据类型转换定义为相关类的一个成员运算符,数据类型转换必须声明为隐式或者显式,以说明怎么使用它.

    C#同意用户进行两种定义的数据类型转换,显式和隐式,显式要求在代码中显式的标记转换,其方法是在原括号里写入目标数据类型.

    对于提前定义的数据类型,当数据类型转换时可能失败或者数据丢失,须要显示转换:

    1.把int数值转换成short,由于short可能不够大,不能包括转换的数值.

    2.把全部符号的数据转换为无符号的数据,假设有符号的变量包括一个负值,会得到不对的结果.

    3.把浮点数转换为整数数据类型时,数字的小数部分会丢失.

    此时应在代码中进行显示数据类型转换,告诉编译器你知道这会有丢失数据的危急,因此编写代码时把这些可能考虑在内.

    注意:假设源数据值使数据转换失败,或者可能会抛出异常,就应把数据类型转换定义为显式.

    定义数据类型转换的语法有点类似于运算符重载.

    比如:隐式类型转换的代码:

    public static inplicit operator float(Current current)

    {}

    和运算符重载同样,数据类型转换必须声明为publicstatic.

    注意:

    当数据类型转换声明为隐式时,编译器能够显式或隐式的调用数据类型转换.

    当数据类型转换声明为显式的,编译器仅仅能显式的调用类型转换.

    案例:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Threading.Tasks;

    namespace 类型转换

    {

        class Program

        {

            static void Main(string[] args)

            {

                try

                {

                    Current balance = new Current(50, 35);

                    Console.WriteLine(balance);

                    Console.WriteLine("balance using tostring() : + " + balance.ToString());

                    //隐式类型转换

                    float balance2 = balance;

                    Console.WriteLine("After converting to float : " + balance2);

                    //显示类型转换

                    balance = (Current)balance2;

                    Console.WriteLine("After converting to Current : " + balance);

                    float t = 45.63f;

                    Current c = (Current)t;

                    Console.WriteLine(c.ToString());

                    checked

                    {

                        balance = (Current)(-50.5);

                        Console.WriteLine("result is : " + balance.ToString());

                    }

                }

                catch (Exception)

                {

                    Console.WriteLine("错误");                

                }

                Console.ReadKey();

            }

        }

        struct Current

        {

            public uint Dollars;

            public ushort Cents;

            //构造函数

            public Current(uint dollars, ushort cents)

            {

                this.Dollars = dollars;

                this.Cents = cents;

            }

            //重写ToString()方法

            public override string ToString()

            {

                return string.Format("{0}.{1,-2:00}", this.Dollars, this.Cents);

            }

            //隐式类型转换

            public static implicit operator float(Current value)

            {

                return value.Dollars + (value.Cents / 100.0f);

            }

            //显示类型转换

            public static explicit operator Current(float f)

            {

                uint dollars = (uint)f;

                ushort cents = (ushort)((f - dollars) * 100);

                return new Current(dollars, cents);

            }

        }

    }

    将设计两个问题:

    1.从float转换为Current得到错误的结果50.34,而不是50.35,----圆整造成的,发生截断问题.

    :假设float值转换为uint,计算机就会截断多余的数字,而不是去圆整它.计算机数据是通过 二进制存储的,而不是十进制,小数部分0.35不能以二进制形式存储.由于舍弃一部分,故实际转换成的数据要小于0.35,即能够用二进制形式存储的值,然后数字乘以100,得到小于35的数字34,有时候这样的阶段是非常危急的,避免这样的错误的方式时确保在数字转换过程中运行智能圆整操作.

    Microsoft编写了一个类System.Convert来完毕该任务.System.Convert包括大量的静态方法来运行各种数字转换,我们要使用的是Convert.ToUint16().注意,在使用System.Convert方法会产生额外的性能损耗,所以仅仅有在须要的时候才使用.

    注意:System.Convert方法还运行他们自己的溢出检查,所以

    Convert.ToUint16((f-dollars)*100);

    这种代码能够不放在checked里面.

    2.在试图转换超出范围的值时,没有发生异常.主要是由于:发生溢出的位置根本不在Main例程中--这是在转换运算符的代码中发生的,该代码在Main()方法中调用,该方法没有标记为checked,其解决方法:

    代码:

            public static explicit operator Current(float f)

            {

                checked

                {

                    uint dollars = (uint)f;

                    ushort cents = Convert.ToUInt16((f - dollars) * 100);

                    return new Current(dollars, cents);

                }            

            }

    explicitimplicit属于转换运算符,乳痈这两者能够让我们自己定义的类型支持相互交换

    explicit表示显示转换,A->B必须进行强制类型转换:B=(B)A

    implicit表示隐式转换,如从B->A仅仅须要直接复制A=B

    隐式转换能够让我们的代码看上去更美丽,更简洁移动,所以最好多使用implicit运算符.只是,假设对象本身在转换时会损失一些信息(如精度),那么我们仅仅能使用explicit运算符,以便在编译期就能警告客户调用.

  • 相关阅读:
    请注意更新TensorFlow 2.0的旧代码
    tf.cast用法
    文件句柄
    Python学习(四)cPickle的用法
    机器都会学习了,你的神经网络还跑不动?来看看这些建议
    Hadoop集群管理之配置文件
    SQL之case when then用法
    关于2014
    Oracle之虚拟索引
    Linux之Ganglia源码安装
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7399649.html
Copyright © 2011-2022 走看看