c# - 如何将 C# 8 中的默认返回值标记为仅对类可为空?

标签 c# generics non-nullable c#-8.0 nullable-reference-types

<分区>

我目前正在尝试将新的 C# 8.0 不可空引用类型功能应用于现有代码,但不知道如何修复以下数据反序列化方法中的 CS8603 警告:

T ReadOptional<T>() where T : IEntity, new()
{
    if (ReadBoolean())
    {
        T instance = new T();
        instance.Read(this); // IEntity method
        return instance;
    }
    else
    {
        // CS8603 Possible null reference return.
        return default;
    }
}

如您所见,如果前面的 bool 值为假,该方法可能会返回 null(类)/default(结构),否则返回 T 实例,它可以是任何实现 IEntity 的东西。

但是,我不能将返回类型标记为 T?,因为如果 T 是一个结构,它实际上不会返回 null,如编译器错误 CS8627 正确提示:

// CS8627: A nullable type parameter must be known to be a value type or non-nullable
// reference type. Consider adding a 'class', 'struct', or type constraint.
T? ReadOptional<T>() where T : IEntity, new()
  • 我无法通过确保 T 具有 class 约束来解决此问题,因为我还希望 struct 实例使用此方法(返回 默认)。
  • 我无法使用具有 struct 约束的 T 创建重载,因为重载不能仅因约束而异。
  • 我可以创建不同命名的方法,但这会破坏库接口(interface),并且会破坏太多依赖于它的代码。

是否有任何语法可以在不破坏为结构返回 default 实例的可能性的情况下修复不可为 null 的警告?

最佳答案

编辑:有一个稍微改进的解决方案 posted here .

浏览a similar C# 8.0 question here ,我填补了我对可空引用类型的知识空白:有一个 null-forgiving operator !可以在这里为我修复警告:

T ReadOptional<T>() where T : IEntity, new()
{
    if (ReadBoolean())
    {
        T instance = new T();
        instance.Read(this); // IEntity method
        return instance;
    }
    else
    {
        return default!; // <-- note the exclamation mark
    }
}

关于c# - 如何将 C# 8 中的默认返回值标记为仅对类可为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54794951/

相关文章:

java - 无法获取通用 ResponseEntity<T>,其中 T 是通用类 "SomeClass<SomeGenericType>"

java - ? Java super 字符串下界

c# - 每个 Visual Studio 选项卡中的小挂锁符号是什么?

c# - 为什么 DirectoryInfo.GetFiles() 匹配与掩码不匹配的文件?

generics - 如何使通用类型可选?

返回类型为 @NonNull 和 Collections 的 Java 泛型

c# - 在可空和非可空 int 上调用 'join' 时类型推断失败

c# - 如何告诉编译器必须初始化属性

c# - 从后面的代码创建 SqlDataSource 过滤器参数

C# 参数化方法数组或参数化方法列表