【C#】【语法】使用默认构造函数初始化类的实例时,各种成员变量的初始值

默认构造函数初始化类的实例

首先摆出这个概念,其实就是最常见的:

MyClass instance = new MyClass();  // 使用默认构造函数

 

可空类型与不可空类型

然后需要明确一下这两个概念。

在C#中,可空类型(nullable types)是指那些可以被赋值为 null 的类型。C# 中有两种主要类型的可空性:

  1. 值类型的可空性:

    • 基本类型:如 intfloatdecimal 等。
    • 枚举类型:如 enum
    • 结构体:如 struct

    当您需要一个值类型可以被赋值为 null 时,可以使用可空类型。例如,int? 表示一个可为空的整型。这里的 ? 表示该类型可以是 null

     
    int? nullableInt = null;
    float? nullableFloat = null;
    decimal? nullableDecimal = null;
     
  2. 引用类型的可空性:

    • 类类型:如 class
    • 接口类型:如 interface
    • 字符串类型:如 string
    • 数组类型:如 int[]

    引用类型默认就可以被赋值为 null,因此它们本身就是可空的。例如:

    string nullableString = null;
    object nullableObject = null;

     

这二者的区别是:

可空的值类型如 intfloatdecimal 等,只有在后面加上问号时,才是可空类型(值类型的可空版本);

而引用类型默认是可以被赋值为 null 的,这意味着它们本身就是可空的。因此,不需要也不应该在引用类型的声明后面加上问号(?)。

 

因此,可空类型就是:1.值类型的可空版本;2.引用类型;不可空类型就是:普通的值类型。

 

使用默认构造函数初始化类的实例时,各种成员变量的初始值

有了上面的基础,以下结论也容易理解:

  1. 值类型成员变量(非可空类型):在类中定义的值类型成员变量默认会被初始化为其类型的默认值。例如:

    • int 的默认值是 0
    • bool 的默认值是 false
    • float 的默认值是 0.0f
  2. 可空类型成员变量(值类型的可空版本):在类中定义的可空类型成员变量默认会被初始化为 null。例如:

    • int? 的默认值是 null
    • float? 的默认值是 null
  3. 引用类型成员变量(如 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` 的支持。
- 使用可空类型可以更灵活地处理值类型,但需要注意性能和逻辑上的正确性。

posted @   ban_boi  阅读(126)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示