Skip to content
C#
类型系统

类型系统

C# 是强类型语言,类型系统是理解所有后续内容的基础。尤其在与 AutoCAD/Revit COM API 交互时,类型转换无处不在。


值类型 vs 引用类型

这是 C# 类型体系最根本的二分法:

对比维度 值类型 (Value Type) 引用类型 (Reference Type)
存储位置 栈(局部变量)/ 随对象堆
赋值行为 复制整个值 复制引用(地址)
默认值 非 null(如 int 默认 0) null
继承自 System.ValueType 直接继承自任意类
可空性 需要 T? 包装(Nullable<T> 默认可 null(C# 8+ 可控制)
示例 int, double, bool, struct, enum string, class, interface, array, delegate
// 值类型:修改副本不影响原值
int a = 5;
int b = a;
b = 10;
Console.WriteLine(a);  // 5

// 引用类型:修改的是同一对象
var list1 = new List<int> { 1, 2, 3 };
var list2 = list1;
list2.Add(4);
Console.WriteLine(list1.Count);  // 4

🚨 这在 AutoCAD 开发中极其重要:Point3d 是值类型(struct),赋值会复制;而 EntityDBObject 是引用类型,多个变量可能指向同一个数据库对象。


内置类型一览

数值类型

C# 关键字 .NET 类型 范围 大小
int Int32 -2.1B ~ 2.1B 4 字节
long Int64 -9e18 ~ 9e18 8 字节
double Double ±5.0e-324 ~ 1.7e308 8 字节
float Single ±1.5e-45 ~ 3.4e38 4 字节
decimal Decimal 28 位精度,适合财务 16 字节
uint UInt32 0 ~ 4.2B 4 字节
double d = 3.14;
float f = 3.14f;      // 必须加 f 后缀
decimal m = 3.14m;    // 必须加 m 后缀
long l = 100L;        // L 后缀
uint u = 100u;        // u 后缀

文本类型

类型 说明 示例
string 不可变 Unicode 字符序列 "hello"
char 单个 Unicode 字符 (16-bit) 'A'
// 字符串插值
string name = "Willow";
string msg = $"Hello, {name}!";

// 逐字字符串(不转义反斜杠)
string path = @"C:\Users\Willow\Documents";

// 原始字符串字面量(C# 11+)
string json = """
    {
        "name": "Willow"
    }
    """;

布尔与特殊类型

bool flag = true;
object obj = 42;          // 所有类型的基类
dynamic dyn = "hello";    // 运行时类型解析(COM 互操作中常用)

💡 dynamic 在 AutoCAD/Revit 开发中较少使用。COM 互操作场景(如操作 Excel)更常见。


Nullable 类型

// 值类型的可空形式
int? age = null;              // 等价于 Nullable<int>
double? pi = 3.14;

// 空值合并操作符
int result = age ?? 0;        // age 为 null 则返回 0

// 空条件操作符
int? length = s?.Length;      // s 为 null 则整个表达式为 null

// Nullable 引用类型(C# 8+)
string? nullableString = null;   // 明确可为 null
string nonNullString = "hello";  // 不应为 null

🚨 AutoCAD/Revit API 中有大量可能返回 null 的方法(如根据 Id 查找实体失败)。务必使用 ?? 或空检查。


struct、enum 与 record

struct(结构体)

// AutoCAD 中 Point3d/Vector3d 就是 struct
public struct Point3d
{
    public double X { get; set; }
    public double Y { get; set; }
    public double Z { get; set; }

    public Point3d(double x, double y, double z)
    {
        X = x; Y = y; Z = z;
    }
}

⚡ 小对象用 struct 可减少堆分配压力。AutoCAD 图形中 Coordinates 就是大量值类型的数组。

enum(枚举)

// AutoCAD 中的颜色索引
public enum AutodeskColor
{
    ByLayer  = 256,
    ByBlock  = 0,
    Red      = 1,
    Yellow   = 2,
    Green    = 3,
    Cyan     = 4,
    Blue     = 5
}

// Flags 枚举(位组合)
[Flags]
public enum FileAccess
{
    Read    = 1 << 0,   // 1
    Write   = 1 << 1,   // 2
    Execute = 1 << 2,   // 4
}
var rw = FileAccess.Read | FileAccess.Write;   // 3

record(记录类型,C# 9+)

// 不可变引用类型,用于数据传输
public record Person(string Name, int Age);

var p1 = new Person("Willow", 25);
var p2 = p1 with { Age = 26 };   // 非破坏性修改

🚨 record 需要 .NET 5+ 运行时支持,在 .NET Framework 4.8 的 AutoCAD/Revit 项目中不可用。


类型转换

// 隐式转换(安全)
int i = 42;
long l = i;          // int → long(无损失)
double d = i;        // int → double(无损失)

// 显式转换(可能损失数据)
double pi = 3.14;
int n = (int)pi;     // 3(截断)

// as / is 操作符
object obj = "hello";
string? s = obj as string;     // 转换失败返回 null,而非抛异常
if (obj is string str)         // 模式匹配 + 声明
    Console.WriteLine(str);

💡 AutoCAD 开发中常用 as 做安全的类型转换:Line line = entity as Line;,如果不是 Line 则返回 null。


数组

// 一维数组
int[] nums = new int[10];
int[] primes = { 2, 3, 5, 7, 11 };

// 多维数组
double[,] matrix = new double[3, 4];

// 交错数组(数组的数组)
int[][] jagged = new int[3][];
jagged[0] = new int[5];

// System.Array 静态方法
Array.Sort(primes);
Array.Reverse(primes);
int idx = Array.BinarySearch(primes, 5);