常见数据类型
C#的类型一般分为值类型、引用类型两大类型。
值类型的实例存放在栈中,引用类型会在栈中放置一个指针指向堆中的某一块内容。
C#为我们内置了几个数据类型供我们使用:
关键词简写 | 对应的类全称(点击可以查看对应的API) | 值范围 | 说明 |
---|---|---|---|
bool | | true、false | |
sbyte | | -128 ~ 127 (-27~27-1) | |
byte | | 0~28-1 | |
short | | -215~215-1 | |
ushort | | 0~216-1 | |
int | | -215~215-1 | |
uint | | 0~232-1 | |
long | | -216~216-1 | |
ulong | | 0~264-1 | |
char | | utf-16 | |
float | | -3.402823e38~3.402823e38 | |
double | | | |
decimal | | ±Nx10k | |
string | | -- | |
另外的两个特殊类型:
dynamic
object
。
其中 dynamic 表示动态类型,这是C#在4.0开始支持的,
dynamic
关键字声明该变量名是个动态变量。具体使用参照 Python,Js 之类的动态语言。但是
dynamic
声明的变量不支持添加属性,但这并不完全绝对,可以参照后续的动态篇会对这部分内容进行介绍。
object
所有类型的父类,C#所有类都是 object的子类。不过上表中介绍的直接父类是 ValueType(表示值类型),但是ValueType的父类仍然是object。
说明:
对于 double 和 float 因为存储数据方式的问题,都存在一个问题:对于 0 或者近0的值不能很好的表达。因为浮点型变量在内存中表示为 1/2n,所以都会存在一个+0和-0两个值。当 一个浮点型判断是不是等于0时,可以正常判断。但是一旦涉及到数学运算的结果与0进行比较的话就会出现问题,比如说
这个判断式是
0.1+0.2 != 0.3
。所以标准的判断方式应该是
true
Math.Abs(0.1+0.2 - 0.3)< ?
这种方式,其中?表示系统接受的误差范围。
而decimal在这方面的准确度就比 double和float高很多。至少不会出现 0.1 + 0.2 != 0.3 这种问题。所以decimal一般用在金额计算这些地方。
类型转换
类型转换是指一个类型的数值通过某种手段转换成另一种类型。
类型转换分为两种方式:默认类型转换、强制类型转换。
默认类型转换
在以下几种情况会触发默认类型转换:
- 当一个子类想转换成它的父类时,
-
当短精度向高精度转换时。
如: byte -> int -> long -> float -> double
参照:
int i = 1;
double d = i;
float f = i;
d = f;
uint ui = 1;
long l = ui;
d = l;
f = l;
这里有几个需要特别注意的地方:
- 无符号和有符号之间的转换,如果无符号的位数与有符号之间的位数一致的话不能默认转换。
- decimal 所有的整型均可以默认转为
,即 除decimal
、double
以外所有数字类型的均可以。float
强制类型转换
数据类型判断 is
:
is
C# 内置了一个关键字 用来 判断 某个变量是否是某个类型
class A
{
}
class B : A
{
}
class C : A
{
}
class Program
{
static void Main()
{
B b = new B();
A a = b;
// 这时候 a 是一个 假装自己是A的B的引用
Console.WriteLine("a is B ? {0}", a is B); // 结果: true
Console.WriteLine("a is A ? {0}", a is A); // true
Console.WriteLine("a is C ? {0}", a is C); // false
}
}
那么
is
有什么用呢?在强制类型转换之前检测一下是否可以转换为目标类型,如果返回值为 false 依旧要转换的话,那么就会报错。
强制类型转换
强制类型转换分为两种:
- 在变量前加目标类型强制转换,这个方法与C/C++、Java的方式一致,具体为:
C c1 = (C)a;// 代码接上
- 使用
关键字,as
表示将变量 x 当做类型Yas
C c2 = a as C;// 代码接上
两种方式的区别:
- 当转型失败时会抛出错误,直接终止代码
- 当转型失败时将c2置为null。当前步骤不会抛出异常,如果对于空引用没有进行处理,那么会在后续中抛出空引用的异常。
值类型的类型转换
在之前的内容中我们提到了小精度到大精度可以默认转换。但是我们在平常使用的过程中会遇到各种情况下的转换,那么这个时候我们就要用到强制转换了,这个时候精度丢失对于我们来说就是可以接受的。
常见的转换方式有:
- 使用类型强制声明转换 例:
long lval = 100; int i = (int)lval;
- 使用 System.Convert类。使用
,其中Convert.ToXXX()
表示转型目标对象。XXX
//Convert 示例代码
long lval = 19293;
var i = Convert.ToInt32(lval);
double d = 10.091;
var dc = Convert.ToDecimal(d);
var dt = Convert.ToDateTime("2019-03-30");
值得注意的是:
Convert
的ToXXX其中XXX使用的是C#类型名称,而不是关键字。
Convert
是个很有用的类,在我们开发工作中会大量的使用这个类进行值的类型转换。
当然后续我们会对其进行更深入的介绍。
更多内容查看 我的博客 或