8.2 类型
C# 支持两种类型:值和引用。值类型包括简单的类型(如 char、int 和 float),枚举和结构。引用包括类,
接口,代理和矩阵。
值与引用的不同在于值的变量直接包含它的数据,而引用的变量只是存储对象的引用。使用引用可以使两个变量
同时引用一个对象,这样对一个变量的操作就会影响另一个引用同一个对象的变量。但每个值都有自己的一份数据
拷贝,使变量之间互不影响。
using System;
class Class1
{
public int Value = 0;
}
class Test
{
static void Main() {
int val1 = 0;
int val2 = val1;
val2 = 123;
Class1 ref1 = new Class1();
Class1 ref2 = ref1;
ref2.Value = 123;
Console.WriteLine("Values: {0}, {1}", val1, val2);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
}
}
输出:
Values: 0, 123
Refs: 123, 123
因为 val1 和 val2 都是值变量(int 类型),每个变量都有自己的存储空间,所以对本地变
量 val1 的赋值不会影响到对 val2 的赋值。
相反地,赋值语句 ref2.Value = 123; 影响 ref1 和 ref2 这两个引用。这两行
Console.WriteLine("Values: {0}, {1}", val1, val2);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
显示 Console.WriteLine 字符串格式化的一些行为,它使用变量作为参数。第一个参数是可以
有多个占位符的字符串,如 {0} 和 {1}。每个占位符指向一个变量,{0} 指向第二个参数,{1}
指向第三个:每个占位符都会被相应的参数代替。在后面会有更进一步地解释。
开发者可以用枚举和结构定义新的值类型,也可以用类,接口和代理等引用类型来声明新的类型。
using System;
public enum Color
{
Red, Blue, Green
}
public struct Point
{
public int x, y;
}
public interface IBase
{
void F();
}
public interface IDerived: IBase
{
void G();
}
public class A
{
protected virtual void H() {
Console.WriteLine("A.H");
}
}
public class B: A, IDerived
{
public void F() {
Console.WriteLine("B.F, implementation of IDerived.F");
}
public void G() {
Console.WriteLine("B.G, implementation of IDerived.G");
}
override protected void H() {
Console.WriteLine("B.H, override of A.H");
}
}
public delegate void EmptyDelegate();
上面是几种声明的例子。在一下的部分中将详细介绍类型的声明。
8.2.1 预定义类型
C# 提供了一套预定义类型,其中的大部分对于C/C++开发者来说很亲切。
预定义类型包括有符号与无符号整数、浮点、布尔、字符和十进制数。有符号数是 sbyte、short、
int 和 long;无符号数是byte、ushort、uint 和 ulong;浮点是 float 和 double。
bool 类型表示:值只能是 true 或 false。这使写和自身建指码和避免错误地在应该用“==”时
使用“=”。
int i = …;
F(i);
if (i = 0) // Bug: the test should be (i == 0)
G();
上面的代码引发一个编译错误,因为 i = 0 的结果是 int 类型,而 if 要求是一个 bool 的结
果。
char 类型表示 Unicode 字符,一个 char 的变量表示一个 16 位的 Unicode 字符。
十进制数适合于各种计算,填补浮点数的进位错误和令人无法接受的表示法。常见的例子是金融
方面的各种计算,比如税率的计算和货币的转换。十进制数是一个有 28 位的数字。
下面列出所有的预定义类型及例子:
类型 描述 例子
object 最基本的类型 object o = null;
string Unicode 字符串类型 string s = "hello";
sbyte 8位有符号byte sbyte val = 12;
short 16位有符号短型 short val = 12;
int 32位有符号整型 int val = 12;
long 64为有符号长整型 long val1 = 12;long val2 = 34L;
byte 8位无符号byte byte val1 = 12;
ushort 16位无符号短型 ushort val1 = 12;
uint 32位无符号整型 uint val1 = 12;uint val2 = 34U;
ulong 64为无符号长整型 ulong val1 = 12;ulong val2 = 34U;ulong val3 = 56L;ulong val4 = 78UL;
float 有符号单精度浮点数 float val = 1.23F;
double 有符号双精度浮点数 double val1 = 1.23;double val2 = 4.56D;
bool 布尔类型;只能是 true 或 false bool val1 = true;bool val2 = false;
char 字符类型;一个 Unicode 字符 char val = 'h';
decimal 28位精确的十进制数 decimal val = 1.23M;
每种预定义类型都是一个系统提供类型的简略表示。比如,int 是 System.Int32 结构的一种缩
略形式,前者必后者更容易使用。
预定义类型,比如 int,除了一小部分特殊的使用以外,大部分都和一般的结构一样。操作符
重载可以定义一个类似预定义类型的新结构类型。例如,一个名为 Digit 结构可以提供和预定
义数字类型同样的数学运算,并且可以定义一个相互转换的规则。
The predefined types employ operator overloading themselves. For example, the
comparison operators == and != have different semantics for different predefined
预定义类型本身也使用重载。例如,比较运算符 == 和 != 与不同的预定义符一起有不同的
语义:
· Two expressions of type int are considered equal if they represent the
same integer value.
· Two expressions of type object are considered equal if both refer to the
same object, or if both are null.
· Two expressions of type string are considered equal if the string
instances have identical lengths and identical characters in each character
position, or if both are null.
·两个 int 类型用它们的值来判断是否相等。
·两个 object 检查它们所引用的对象是否一样来判断是否相等。
·两个 string 用它们的长度和每个位置的上的元素是否相同来判断它们是否相等,或者
两者都为 null。
using System;
class Test
{
static void Main() {
string s = "Test";
string t = string.Copy(s);
Console.WriteLine(s == t);
Console.WriteLine((object)s == (object)t);
}
}
输出:
True
False
第一个比较的是 string 类型,而第二个比较的是 object 类型。
本文地址:http://com.8s8s.com/it/it46148.htm