我编写了两个抽象类来表示实体的基类:一个其中 Id
属性是一个 int,另一个允许使用泛型类型参数 TId
指定 Id
属性的类型:
/// <summary>
/// Represents the base class for all entities.
/// </summary>
[System.Serializable]
public abstract class BaseEntity
{
/// <summary>
/// Gets or sets the ID of the entity.
/// </summary>
public int Id { get; set; }
}
/// <summary>
/// Represents the base class for all entities that have an ID of type <typeparamref name="TId"/>.
/// </summary>
/// <typeparam name="TId">
/// The type of the <see cref="Id"/> property.
/// </typeparam>
[System.Serializable]
public abstract class BaseEntity<TId>
{
/// <summary>
/// Gets or sets the ID of the entity.
/// </summary>
public TId Id { get; set; }
}
这些类定义在一个核心程序集中,我几乎在我所做的所有项目中都使用它们。自从 C# 8.0 发布以来,我一直在尝试启用 可空引用类型,到目前为止效果还不错。
然而,在
BaseEntity<TId>
的情况下,编译器会发出警告:
我理解这个警告,但似乎无法解决我的问题。更具体地说,我想允许从以下类型派生的类型的声明:未初始化的非可空属性“Id”。考虑将该属性声明为可空。
System.String
,即BaseEntity<string>
- 任何值类型,如
BaseEntity<System.Guid>
或自定义结构
System.String
不是值类型,所以似乎不可能实现:如果我将TId
限制为结构体(BaseEntity<TId> where TId : struct
),我将无法再声明BaseEntity<string>
。到目前为止,我找到的唯一解决方案(?)是使用默认值初始化
Id
属性并使用!
运算符来禁用警告。/// <summary>
/// Represents the base class for all entities that have an ID of type <typeparamref name="TId"/>.
/// </summary>
/// <typeparam name="TId">
/// The type of the <see cref="Id"/> property.
/// </typeparam>
[System.Serializable]
public abstract class BaseEntity<TId>
{
/// <summary>
/// Gets or sets the ID of the entity.
/// </summary>
public TId Id { get; set; } = default!;
}
然而,我想要明确代码的意图:即
TId
可以是值类型(例如short、long、System.Guid
等),或者是System.String
。
这是否可能?
TId
为空的引用,您可以使用where TId : notnull
来禁止class Entity : BaseEntity<string?>
这种用法。 - Orace