c#之用户定义的数据类型转换介绍

c# 允许用户进行两种定义的数据类型转换,显式和隐式,显式要求在代码中显式的标记转换,其方法是在圆括号中写入目标数据类型。

对于预定义的数据类型,当数据类型转换时可能失败或丢失某些数据,需要显式转换,

1 把int数值转换成short时,因为short可能不够大,不能包含转换的数值。

2 把有符号的数据转换为无符号的数据,如果有符号的变量包含一个负值,会得到不正确的结果。

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

此时应在代码中进行显式数据类型,告诉边起义你知道这会有丢失数据的危险,因此编写代码时套把这些可能考虑在内。

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

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

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

例如  :隐式类型转换:


代码如下:

public static implicit operator float(Current current)
{
}

和运算符重载相同,数据类型转换必须声明为public和static。

注意:

当数据类型转换声明为隐式时,编译器可以显式或者隐式的调用数据类型转换。

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

下面是个小例子:


代码如下:

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

namespace 类型转换
{
struct Current
{
public uint Dollars;
public ushort Cents;

public Current(uint dollars, ushort cents)
{
this.Dollars = dollars;
this.Cents = cents;
}

public override string ToString()
{
return string.Format("{0}.{1,-2:00}",Dollars,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);
}

}

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 (System.Exception ex)
{
Console.WriteLine("Exception occurred:" + ex.Message);
}
Console.ReadKey();
}
}
}

将涉及到两个问题:

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

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

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

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


代码如下:

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);
}
}<SPAN style="FONT-FAMILY: Arial, Verdana, sans-serif">
</SPAN>

(0)

相关推荐

  • 再议C#中的装箱与拆箱的问题详解

    上一篇写了一下装箱拆箱的定义和IL分析,这一篇我们看下使用泛型和不使用泛型引发装箱拆箱的情况1.使用非泛型集合时引发的装箱和拆箱操作 看下面的一段代码: 复制代码 代码如下: var array = new ArrayList();array.Add(1);array.Add(2); foreach (int value in array){Console.WriteLine("value is {0}",value);} 代码声明了一个ArrayList对象,向ArrayList中添

  • 解析C#中的装箱与拆箱的详解

    装箱和拆箱是值类型和引用类型之间相互转换是要执行的操作. 1. 装箱在值类型向引用类型转换时发生2. 拆箱在引用类型向值类型转换时发生光上述两句话不难理解,但是往深处了解,就需要一些篇幅来解释了.我们先看装箱时都会发生什么事情,下面是一行最简单的装箱代码 复制代码 代码如下: object obj = 1; 这行语句将整型常量1赋给object类型的变量obj: 众所周知常量1是值类型,值类型是要放在栈上的,而object是引用类型,它需要放在堆上:要把值类型放在堆上就需要执行一次装箱操作.这行

  • C#实现装箱与拆箱操作简单实例

    本文以一个简单实例讲述了C#装箱和拆箱操作的实现方法,简单来说装箱是将值类型转换为引用类型:拆箱是将引用类型转换为值类型,是涉及栈和堆的使用方面的东西,学过C#的人应该都知道,所以这里就不哆嗦了,本例代码也是面向C#新手的,非常简单. 具体实现代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace UnBoxing { class Program {

  • C#基础之数据类型转换

    int x; long y = 123456789101112; x = (int)y; Console.WriteLine(x); 输出结果: 我们知道long类型的取值范围是-9223372036854775805~+9223372036854775807:int类型的是:-2147483648~+2147483647 上面的代码中,由于long变量的值超过了int能容纳的最大值,造成了数据的丢失:像这样有可能造成数据丢失或引发异常的任何转换都需要执行显式转换(explicit); 相反的就

  • C#编程自学之数据类型和变量三

    了解了数据类型与变量的基本概念之后,我们来讨论数据类型的转换与装箱与拆箱!装箱和取消装箱使我们能够统一地来考察类型系统,其中任何类型的值最终都可以按对象处理. 一.数据类型转换 在编程时 我们有时候会遇到将一个类型的变量转换成另一种数据类型,我们称它为数据类型的转换,C#数据类型的转换有两种方式如下: 1.默认安全的数据类型转换 默认安全的数据类型转换:我们称之为 隐式的数据类型转换,什么是隐式的数据类型转换?隐式的数据类型转换就是数据类型的低范围(参考C#数据类型与变量一中的数据类型的范围)向

  • c#装箱和拆箱知识整理

    1.装箱和拆箱是一个抽象的概念 2.装箱是将值类型转换为引用类型 : 拆箱是将引用类型转换为值类型 利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的值相互转换,将值类型与引用类型链接起来 例如: 复制代码 代码如下: int val = 100; object obj = val; Console.WriteLine ("对象的值 = {0}", obj); 这是一个装箱的过程,是将值类型转换为引用类型的过程 复制代码 代码如下: int val = 100; obj

  • 浅析C#数据类型转换的几种形式

    1.Convert.ToInt32(); //转换成32位的整数.2.变量.ToString();/最常见的转换成 字符串.3."订单"+2514 //后面的数字会转换为字符串.4.((类名A)对象名X) //强行将 对象X 转换成 A类 的对象.5.int.Parse(string);把字符串型转换成其他类型.6.还有,如果要转换成的类型为引用类型,还可以用 as teacher tea = teahcer();如 student stu = tea as student; (1)

  • c#之用户定义的数据类型转换介绍

    c# 允许用户进行两种定义的数据类型转换,显式和隐式,显式要求在代码中显式的标记转换,其方法是在圆括号中写入目标数据类型. 对于预定义的数据类型,当数据类型转换时可能失败或丢失某些数据,需要显式转换, 1 把int数值转换成short时,因为short可能不够大,不能包含转换的数值. 2 把有符号的数据转换为无符号的数据,如果有符号的变量包含一个负值,会得到不正确的结果. 3 把浮点数转换为整数数据类型时,数字的小数部分会丢失. 此时应在代码中进行显式数据类型,告诉边起义你知道这会有丢失数据的危

  • Spring Security用户定义 

    目录 一.基于内存 二.基于mybatis 基于内存的和基于数据库的,下面我给大家简单介绍一下这两种方式. 一.基于内存 Spring Security中的配置: @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception {     InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();    

  • C/C++中数据类型转换详解及其作用介绍

    目录 概述 不同类型数据间的转换 隐式类型转换 强制类型转换 自己声明的类型转换 转换构造函数 类型转换函数 案例 应用 概述 在日常的开发中, 我们经常会用到数据类型转换, 所以我们要对数据类型转换有一定的了解. 不同类型数据间的转换 在 C++ 中, 某些标准类型的数据之间可以自动转换. 隐式类型转换 隐式类型转换: 由 C++ 编译系统自动完成的, 我们无需干预. 例如: int main() { int a = 6; a = a + 3.5; cout << a << en

  • C#用户定义类型转换详解

    C#用户定义类型转换 •用于自定义类和结构能够进行隐式转换和显示转换.例如:将一个自定义类类型转换成整型,浮点型等,反之亦然. C#提供隐式转换和显式转换 •隐式转换:编译器自动执行转换•显式转换:编译器只在使用显式转换运算符时才执行转换声明隐式转换的语法如下.注:所有用户定义转换必须使用public和static修饰符 复制代码 代码如下: public static implicit operator TargetType(SourceType Identifier){       ... 

  • Arduino 数据类型转换(单机片)详细介绍

    Arduino 数据类型转换 如何轻松玩转Arduino单片机,当我在进行数据转换的时候,遇到了问题,尝试了C语言和C++中的好多函数,都没有达到将float型数据转换为char型的目的.苦苦查阅资料后,终于找到了一个大神级函数!!!dtostrf(),可以轻松实现数据类型from   float   to  char .            get it 格式如下: char* dtostrf(double _val,signed char _width, unsigned char pre

  • 微信小程序 定义全局数据、函数复用、模版等详细介绍

    微信小程序 定义全局数据.函数复用.模版等问题总结: 1.如何定义全局数据 在app.js的App({})中定义的数据或函数都是全局的,在页面中可以通过var app = getApp();  app.function/key的方式调用,不过我们没有必要再app.js中定义全局函数. 2.如何实现代码的复用 函数的复用: test.js test: function(){ } module.exports={ test:test } other.js var common = require('

  • 深入讲解C++数据类型转换的相关函数的知识

    C++数据类型转换以及转换构造函数 标准数据类型之间的转换 在C++中,某些不同类型数据之间可以自动转换,例如 int i = 6; i = 7.5 + i; 编译系统对 7.5是作为double型数处理的,在求解表达式时,先将6转换成double型,然后与7.5相加,得到和为13.5,在向整型变量i赋值时,将13.5转换为整数13,然后赋给i.这种转换是由C++编译系统自动完成的,用户不需干预.这种转换称为隐式类型转换. C++还提供显式类型转换,程序人员在程序中指定将一种指定的数据转换成另一

  • Pandas实现数据类型转换的一些小技巧汇总

    前言 Pandas是Python当中重要的数据分析工具,利用Pandas进行数据分析时,确保使用正确的数据类型是非常重要的,否则可能会导致一些不可预知的错误发生. Pandas 的数据类型:数据类型本质上是编程语言用来理解如何存储和操作数据的内部结构.例如,一个程序需要理解你可以将两个数字加起来,比如 5 + 10 得到 15.或者,如果是两个字符串,比如「cat」和「hat」,你可以将它们连接(加)起来得到「cathat」.尚学堂•百战程序员陈老师指出有关 Pandas 数据类型的一个可能令人

  • python3的数据类型及数据类型转换实例详解

    之前介绍过python开发工具Jupyter的使用,今天继续讲解python的数据类型,python中有整型.浮点型.字符串.布尔类型,我们重点介绍布尔类型的运算,以及不同数据类型之间的转换.使用Jupyter运行的时候有两个快捷键,Shift + Enter执行本单元,并且光标会移动到下一个单元:Ctrl + Enter是执行本单元,并且光标留在本单元. 在python的数据类型中,我们定义变量a = 1, 那么a是一个整型:定义变量b = 1.2,那么b就是一个浮点型,浮点型还有一种科学记数

  • java数据类型转换陷阱包括列表陷阱

    java 数据类型转换的陷阱 本文通过时间数值的处理来研究一下数据类型的自动转换.我们知道:System.currentTimeMillis():返回的是long类型的数值.当计算时间相加的时候,如果不注意数据类型的自动转换,则很容易出现问题,如下所示: Date expiration = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 365 * 5); 上面例子本意是求5年后的过期时间,而实际输出的结果却比当前时间还早的

随机推荐