【C#】【语法】使用默认构造函数初始化类的实例时,各种成员变量的初始值
默认构造函数初始化类的实例
首先摆出这个概念,其实就是最常见的:
MyClass instance = new MyClass(); // 使用默认构造函数
可空类型与不可空类型
然后需要明确一下这两个概念。
在C#中,可空类型(nullable types)是指那些可以被赋值为 null
的类型。C# 中有两种主要类型的可空性:
-
值类型的可空性:
- 基本类型:如
int
、float
、decimal
等。 - 枚举类型:如
enum
。 - 结构体:如
struct
。
当您需要一个值类型可以被赋值为
null
时,可以使用可空类型。例如,int?
表示一个可为空的整型。这里的?
表示该类型可以是null
。int? nullableInt = null; float? nullableFloat = null; decimal? nullableDecimal = null;
- 基本类型:如
-
引用类型的可空性:
- 类类型:如
class
。 - 接口类型:如
interface
。 - 字符串类型:如
string
。 - 数组类型:如
int[]
。
引用类型默认就可以被赋值为
null
,因此它们本身就是可空的。例如:string nullableString = null; object nullableObject = null;
- 类类型:如
这二者的区别是:
可空的值类型如 int
、float
、decimal
等,只有在后面加上问号时,才是可空类型(值类型的可空版本);
而引用类型默认是可以被赋值为 null
的,这意味着它们本身就是可空的。因此,不需要也不应该在引用类型的声明后面加上问号(?
)。
因此,可空类型就是:1.值类型的可空版本;2.引用类型;不可空类型就是:普通的值类型。
使用默认构造函数初始化类的实例时,各种成员变量的初始值
有了上面的基础,以下结论也容易理解:
-
值类型成员变量(非可空类型):在类中定义的值类型成员变量默认会被初始化为其类型的默认值。例如:
int
的默认值是0
。bool
的默认值是false
。float
的默认值是0.0f
。
-
可空类型成员变量(值类型的可空版本):在类中定义的可空类型成员变量默认会被初始化为
null
。例如:int?
的默认值是null
。float?
的默认值是null
。
-
引用类型成员变量(如
string
,class
类型等):在类中定义的引用类型成员变量默认会被初始化为null
。
举例:
public class MyClass { public int IntMember; // 默认值为 0 public int? NullableInt; // 默认值为 null public string StringMember; // 默认值为 null public bool BoolMember; // 默认值为 false public float FloatMember; // 默认值为 0.0f public float? NullableFloat;// 默认值为 null }
在 C# 中,**值类型**(如 `int`、`float`、`decimal`、枚举类型 `enum` 和结构体 `struct`)默认情况下是不可为空的。如果需要让它们支持 `null` 值,则必须使用 **可空类型**(Nullable Types),即在类型后面加上 `?`。
### 已知信息
1. **值类型的特性**:
- 值类型直接存储数据,不能为 `null`。
- 默认值由其类型的零值决定(例如,`int` 的默认值是 `0`,`bool` 的默认值是 `false`)。
2. **可空类型**:
- 可空类型允许值类型存储 `null` 值。
- 使用语法:`T?`,其中 `T` 是值类型(如 `int?`、`float?` 等)。
- 实际上,`T?` 是 `System.Nullable<T>` 的简写形式。
### 如何让值类型支持 `null`
#### 1. 基本类型(如 `int`、`float`、`decimal`)
这些基本类型本身是值类型,默认情况下不能为 `null`。如果需要支持 `null`,可以使用 `?`:
int? nullableInt = null; // 可空整数 float? nullableFloat = null; // 可空浮点数 decimal? nullableDecimal = null; // 可空十进制数 Console.WriteLine(nullableInt == null); // 输出 True
#### 2. 枚举类型(`enum`)
枚举类型也是值类型,默认情况下不能为 `null`。如果需要支持 `null`,同样可以使用 `?`:
public enum Color { Red, Green, Blue } Color? nullableColor = null; // 可空枚举 Console.WriteLine(nullableColor == null); // 输出 True
#### 3. 结构体(`struct`)
结构体是用户定义的值类型,默认情况下也不能为 `null`。如果需要支持 `null`,也需要使用 `?`:
public struct Point { public int X; public int Y; } Point? nullablePoint = null; // 可空结构体 Console.WriteLine(nullablePoint == null); // 输出 True
### 可空类型的工作原理
在 C# 中,`T?` 是 `System.Nullable<T>` 的语法糖。`Nullable<T>` 是一个泛型结构体,用于包装值类型并允许其存储 `null` 值。
#### 示例:`int?` 的内部实现
int? nullableInt = null; // 实际上等价于: Nullable<int> nullableInt = new Nullable<int>();
`Nullable<T>` 提供了两个重要的属性:
- **`HasValue`**:指示当前值是否为非 `null`。
- **`Value`**:获取实际的值(如果 `HasValue` 为 `false`,访问 `Value` 会抛出异常)。
示例代码:
int? nullableInt = 42; if (nullableInt.HasValue) { Console.WriteLine($"Value is: {nullableInt.Value}"); // 输出 42 } else { Console.WriteLine("Value is null"); }
### 注意事项
1. **引用类型不需要 `?`**:
- 引用类型(如 `string`、类)本身就是可空的,默认值是 `null`,因此不需要使用 `?`。
- 例如,`string?` 在 C# 8.0 引入的可空引用类型上下文中才有意义(用于显式标记可能为 `null` 的引用类型)。
2. **性能影响**:
- 可空类型会引入额外的开销,因为它们实际上是一个包装器(`Nullable<T>`)。
- 如果性能非常关键且不需要支持 `null`,应避免使用可空类型。
3. **数据库映射**:
- 在与数据库交互时,可空类型非常有用。例如,数据库中的 `NULL` 值可以通过 `int?` 或 `DateTime?` 来表示。
---
### 总结
- **所有值类型(如 `int`、`float`、`decimal`、`enum`、`struct`)都需要加上 `?` 才能成为可空类型**。
- 可空类型通过 `System.Nullable<T>` 实现,提供了对 `null` 的支持。
- 使用可空类型可以更灵活地处理值类型,但需要注意性能和逻辑上的正确性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)