您的位置:首页 > 编程语言 > C#

C#笔记(转换)

2018-03-11 00:23 141 查看
转换是接受一个类型的值并使用它作为另一个类型的 等价值 的过程。

1 转换的类型

转化类型可分为 预定义用户自定义的

其中预定义又可分为:

数字转换:其又可分为隐式或显式

装箱/拆箱:装箱用于将任何 值类型 转换为:
object
类型或
System.ValueType
类型,拆箱用于还原

引用转换:多是基类与派生类的转化

用户自定义的就需要使用到
implicit
explicit
关键字了。

1.1 隐式转换

有些类型的转换不会丢失数据或精度,比如8位的数值转换为16位的数值,语言会自动做这些转换,这叫做 隐式转换

零扩展:从更小的无符号类型转换为更大的无符号类型时,目标类型多出来的最高位都以 0 进行填充,这叫做 零扩展

符号扩展:对于有符号类型的转换而言,额外的高位用 源表达式的符号位 进行填充,这样叫做 符号扩展

1.2 显式转换和强制转换

如果有长类型转换为短类型,目标类型也许无法在不损失数据的情况下提供源值,很多情况下会导致数据溢出或丢失。此时还是想要继续转换,就必须使用 显式转换强制转换表达式)。

示例:

(sbyte) varl1; // sbyte 是目标类型,var1 源表达式


1.2.1 溢出检测上下文

显式转化可能会丢失数据并且不能在目标类型中同等地表示源值,对于整数类型,可以通过
checked
运算符和
checked
语句来检测结果是否溢出。

代码片段是否被检测称作为 溢出检测上下文,默认的检测上下文是不检查。

checked
运算符和
unchecked
运算符:

ushort sh = 2000;
byte sb;
sb = unchecked((byte) sh); // 大多数重要的位丢失了
sb = checked((byte) sh); // 抛出overflowException异常


checked
语句和
unchecked
语句,它们与运算符的不同是,它们控制的是语句块:

byte sb;
ushort sh
4000
=2000;
checked
{
sb = (byte) sh;
}


1.2.1 显式数据的丢失状况

数值类型

类型范围大小
sbyte-128 到 127有符号 8 位整数
byte0到255无符号 8 位整数
charU+0000 到 U+ffff16 位 Unicode 字符
short-32,768 到 32,767有符号 16 位整数
ushort0 到 65,535无符号 16 位整数
int-2,147,483,648 到 2,147,483,647有符号 32 位整数
uint0 到 4,294,967,295无符号 32 位整数
long-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807有符号 64 位整数
ulong0 到 18,446,744,073,709,551,615无符号 64 位整数
decimal(-7.9 x 1028 到 7.9 x 1028) / 100 到 28128 位精确的十进制值,28-29 有效位数
float±1.5e−45 到 ±3.4e3832 位单精度
double±5.0e−324 到 ±1.7e30864 位双精度
float
double
转化为整数类型时,源值会舍掉小数,如果舍掉小数后的值仍不在目标类型的范围内,就根据 溢出检测上下文 来进行下一步操作。

2 引用转换

引用转换接受源引用并返回 一个指向堆中同一位置的引用,只是把引用标记为其他类型,而实际上二者都指向内存中的相同对象

2.1 隐式引用转换

与自动实现的隐式数值转换类似,还有隐式引用转换:

所有引用类型都可以被隐式转换为
object
类型

如何类型都可以隐式转换到他继承的接口

类可以隐式转换到他继承链中的任何类,以及它实现的任何接口

3 装箱和拆箱

包括值类型在类的所有C#类型都派生值
object
类型,只是 值类型 是高效轻量的类型

3.1

默认情况下,值类型在堆上不包括它们的对象组件,如果需要对象组件,可以使用装箱实现。

装箱是 隐式转换,它接受值类型的值,根据这个值在堆上创建一个完整的引用类型对象并返回其引用。其中原始值类型和返回的引用类型,每个都可以独立操作,互不干扰。

int i =12;
object oi = null;
oi = i;


3.2 拆箱

拆箱是把装箱后的对象转换回值类型的过程,拆箱是显式转换。

int i =10;
object oi = i;
int j = (int) oi; // 将一个值拆箱为非原始类型时会抛出InvalidCastException异常


4 用户自定义转换

在定义类和结构的时候,可以同时为其自定义转换。

定义时要点:

使用
implicit
explicit
关键字,前者是隐式,后者是显式,二者后跟
operator
运算符、目标类型

声明时需要
public
static
修饰符

二者不能通过继承关联,二者必须是不同类型

二者都不能是
object
类型或接口类型

例如:

public static implicit operator int(Person p)
{
return p.Age;
}


5
is
运算符

有些转换是不成功的,就如同用于检测整数转换是否成功的
checked
运算符一样,
is
运算符用于测定以下方式是否转换成功,成功返回
true


引用转换

装箱/拆箱转换

语法:

Expr is TargetType; // 可以使用 if 语句判断是否为 true,再进行转换


6
as
运算符

as
运算符与强制转换运算符类似,只是它不抛出异常,如果失败,它返回的是
null
,所以赋值变量之前要先检查是否为
null


语法:

Expr as TargetType;


只能用于引用转换和装箱转换(没有拆箱转换)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐