C# 中的泛型参数区分值类型或引用类型

本文最后更新于 2021年4月4日 晚上

在实现 Stack 的过程中, 给定一个泛型参数 T, 假设 T 是引用类型, 则可以在栈为空的时候返回 null, 但如果是值类型就不行了, 那如何判断泛型参数是值类型还是引用类型呢? 这个就是这篇文章需要探索的内容.

IStack 接口定义如下所示:

1
2
3
4
5
6
7
8
public interface IStack<T> {
Boolean IsEmpty { get; }
Int64 Count { get; }
void Push(T value);

T Pop();
T Top { get; }
}

在实现过程中, 主要是 Pop 方法和 Top 属性二者的实现需要考虑值类型和引用类型的区别, 因为值类型没有 null.

在需要返回 T 类型对象的情况下, 有如下两种处理方式:

  1. 如果对值类型和引用类型合并考虑, 则可以返回 default(T). 这样的话, 如果 T 是引用类型, 则返回 null, 如果是值类型, 则返回对应的默认值(比如 int 默认是 0, char 默认是 \0 等等).

  2. 如果对值类型和引用类型分开考虑, 则可以在实现上对 T 添加泛型约束:

    1
    2
    3
    4
    // 对 T 添加泛型约束, 表明 T 是引用类型的.
    public class Stack<T> : IStack<T> where T : class {
    //...
    }

C# 中的泛型参数区分值类型或引用类型
https://blog.rayy.top/2019/09/09/2019-2019-09-09-CSharpGenericsOptional/
作者
貘鸣
发布于
2019年9月9日
许可协议