在C#中,数据类型是编程的基础,用于定义变量和方法可以存储的数据种类。C#的数据类型分为两大类:值类型(Value Types) 和 引用类型(Reference Types)。此外,C#还支持一些特殊的类型,如指针类型和可空类型。
值类型直接存储数据值,存储在栈内存中,具有高性能特点。
这些类型是C#语言的内置类型,用于存储数值数据。
int age = 25;
Console.WriteLine(age); // 输出:25
double price = 99.99;
Console.WriteLine(price); // 输出:99.99
decimal salary = 12345.6789m;
Console.WriteLine(salary); // 输出:12345.6789
bool isApproved = true;
Console.WriteLine(isApproved); // 输出:True
char letter = 'A';
Console.WriteLine(letter); // 输出:A
枚举是一种特殊的值类型,用于定义一组命名的常量。
enum DayOfWeek
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
DayOfWeek today = DayOfWeek.Monday;
Console.WriteLine(today); // 输出:Monday
结构体是一种用户定义的值类型,用于封装一组相关的数据。
struct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
}
Point p = new Point(10, 20);
Console.WriteLine($"点的坐标是 ({p.X}, {p.Y})"); // 输出:点的坐标是 (10, 20)
引用类型存储对数据的引用,而不是数据本身。数据存储在堆内存中,而变量存储的是指向堆内存的引用。
类是C#中最常见的引用类型,用于定义对象的结构和行为。
class Person
{
public string Name;
public int Age;
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
Person person = new Person("张三", 30);
Console.WriteLine($"{person.Name} 的年龄是 {person.Age} 岁");
// 输出:张三 的年龄是 30 岁
接口是一种引用类型,用于定义一组方法和属性的契约,但不提供实现。
interface IAnimal
{
void MakeSound();
}
class Dog : IAnimal
{
public void MakeSound()
{
Console.WriteLine("汪汪叫");
}
}
IAnimal animal = new Dog();
animal.MakeSound(); // 输出:汪汪叫
数组是一种引用类型,用于存储一组相同类型的元素。
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
Console.WriteLine(numbers[2]); // 输出:3
字符串是一种特殊的引用类型,用于存储文本数据。字符串是不可变的。
string greeting = "你好,世界!";
Console.WriteLine(greeting.ToUpper()); // 输出:你好,世界!
委托是一种引用类型,用于定义方法的签名,并可以将方法作为参数传递。
delegate void MyDelegate(string message);
void PrintMessage(string message)
{
Console.WriteLine(message);
}
MyDelegate del = PrintMessage;
del("你好,委托!"); // 输出:你好,委托!
dynamic关键字允许在运行时动态解析类型,绕过编译时检查。
dynamic obj = "你好";
Console.WriteLine(obj.ToUpper()); // 输出:你好
可空类型允许值类型存储null值。
int? nullableInt = null;
Console.WriteLine(nullableInt.HasValue ? nullableInt.Value.ToString() : "无值");
// 输出:无值
指针类型用于存储变量的内存地址。指针类型主要用于不安全代码中,用于直接操作内存。
unsafe
{
int value = 10;
int* ptr = &value;
Console.WriteLine(*ptr); // 输出:10
}
C#支持隐式类型转换(自动转换)和显式类型转换(强制转换)。
int intValue = 100;
double doubleValue = intValue; // 隐式类型转换
Console.WriteLine(doubleValue); // 输出:100.0
doubleValue = 99.99;
intValue = (int)doubleValue; // 显式类型转换,可能丢失精度
Console.WriteLine(intValue); // 输出:99
此外,还可以通过自定义转换运算符(implicit和explicit)实现用户定义的类型转换。
装箱(Boxing)和拆箱(Unboxing)是值类型和引用类型之间的转换过程,主要用于将值类型转换为引用类型(装箱)或从引用类型还原为值类型(拆箱)。
将值类型转换为引用类型,通常用于将值类型存储到集合中。
int intValue = 10;
object obj = intValue; // 装箱
Console.WriteLine(obj); // 输出:10
装箱时,值类型会被包装成一个对象,并存储在堆内存中。
将引用类型还原为值类型。
object obj = 10;
int intValue = (int)obj; // 拆箱
Console.WriteLine(intValue); // 输出:10
拆箱时,需要显式地将引用类型强制转换为目标值类型。