C# 无法使“notnull”类型可为空

2023-12-30

我正在尝试创建一个类似于 Rust 的类型Result或哈斯克尔的Either到目前为止我已经做到了:

public struct Result<TResult, TError>
    where TResult : notnull
    where TError : notnull
{
    private readonly OneOf<TResult, TError> Value;
    public Result(TResult result) => Value = result;
    public Result(TError error) => Value = error;

    public static implicit operator Result<TResult, TError>(TResult result)
        => new Result<TResult, TError>(result);

    public static implicit operator Result<TResult, TError>(TError error)
        => new Result<TResult, TError>(error);

    public void Deconstruct(out TResult? result, out TError? error)
    {
        result = (Value.IsT0) ? Value.AsT0 : (TResult?)null;
        error = (Value.IsT1) ? Value.AsT1 : (TError?)null;
    }  
}

鉴于这两种类型的参数都被限制为notnull,为什么它会抱怨(任何有可空类型参数的地方?在其后签名):

必须知道可为空类型参数是值类型或不可为空引用类型。考虑添加“类”、“结构”或类型约束。

?


我在 .NET Core 3 上使用 C# 8,并启用了可空引用类型。


基本上,您要求的东西无法在 IL 中表示。可空值类型和可空引用类型是非常不同的东西,虽然它们在源代码中看起来很相似,但 IL 却非常不同。值类型的可为空版本T是一种不同的类型(Nullable<T>) 而引用类型的可为空版本T is the same类型,其属性告诉编译器期望什么。

考虑这个更简单的例子:

public class Foo<T> where T : notnull
{
    public T? GetNullValue() => 
}

出于同样的原因,这是无效的。

如果我们约束T是一个结构体,那么生成的 ILGetNullValue方法的返回类型为Nullable<T>.

如果我们约束T为不可为 null 的引用类型,则为以下生成的 ILGetNullValue方法的返回类型为T,但具有可空性方面的属性。

编译器无法为具有两者返回类型的方法生成 ILT and Nullable<T>同时。

这基本上是可空引用类型根本不是 CLR 概念的结果 - 它只是编译器的魔法,可以帮助您在代码中表达意图并让编译器在编译时执行一些检查。

但错误消息并不像想象的那么清楚。T已知为“值类型或不可为空的引用类型”。更精确(但明显更冗长)的错误消息是:

可以为 null 的类型参数必须是值类型,或者是不可为 null 的引用类型。考虑添加“类”、“结构”或类型约束。

那时,错误将合理地适用于我们的代码 - 类型参数不是“已知是值类型”,也不是“已知是不可为空的引用类型”。已知是两者之一,但编译器需要知道which.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 无法使“notnull”类型可为空 的相关文章

  • 如何在 Caliburn.Micro 中使用 Conductor 的依赖注入

    我有时用Caliburn Micro http caliburnmicro com创建应用程序 使用最简单的 BootStrapper 我可以像这样使用 IoC 容器 SimpleContainer private SimpleContai
  • 是否保证 sizeof(T[N]) == N * sizeof(T) ?

    我一直假设 N 个元素类型的数组的大小T 由返回sizeof保证正好是N次sizeof T The 对这个问题的评论 https stackoverflow com questions 46457449 is it always the c
  • 更改图像颜色与透明背景

    我需要使用 c System Drawings 将透明背景上带有绿色圆圈的图像加载到位图图像中 这是最简单的部分 但是 我需要在将其添加到更大的图像之前更改圆圈的颜色 而不影响周围的透明度 就我而言 我需要将圆圈颜色更改为黄色并将其添加为太
  • C++:字符串流有什么好处?

    谁能告诉我一些在 C 中使用字符串流的实际例子 即使用流插入和流提取运算符输入和输出到字符串流 您可以使用字符串流来转换任何实现operator lt lt 到一个字符串 include
  • 错误:“运行所选代码生成器时出错:包恢复失败”

    我正在尝试将控制器添加到 ASP NET Core 项目中的解决方案中 当我尝试这样做时 我收到此错误 我收到相同的消息 为控制器添加最小依赖项和完整依赖项 我也有这个问题 使用实体框架添加控制器 gt 带有操作的 API 控制器 将给出
  • Monitor.Pulse & Wait - 意外行为

    http www codeproject com Articles 28785 Thread synchronization Wait and Pulse demystified http www codeproject com Artic
  • 提取单花括号内的值

    我想要一个收藏 value 一个字符串使用正则表达式 例如 lorem ipsum field1 lorem ipsum field2 lorem ipsum field1 lorem ipsum field2 field3 我会得到 fi
  • 值类型如何实现引用类型

    我遇到了一个值类型正在实现 ref 的场景 类型 只是想知道这怎么可能 幕后发生了什么 结构体是值类型 接口是引用 类型但结构可以实现接口而不会出现任何错误 有什么想法吗 提前致谢 实际上 它同时以两种不同的方式进行 首先 任何值类型都可以
  • 使用 LINQ 展平嵌套字典

    所以我有一本形式的字典Dictionary
  • UI 线程正在阻塞调用 COM 对象的后台线程

    我正在开发一个通过第三方 COM 库与外部设备通信的应用程序 我试图让与设备的所有通信都通过后台线程 以防止通信问题搞砸我的应用程序 并消除在 UI 线程中进行通信所引入的一些其他复杂性 问题是 每当发生导致主 UI 线程阻塞的情况 即调用
  • 在 Java 类型参数中, 仅意味着严格的子类型?或者 E 也足够了吗?

    在 Java 类型参数中 是否仅意味着严格的子类型 或者 E 也足够了吗 这并不严格 E就足够了
  • 如何在Unity Inspector中创建多维数组?

    如何在 Unity Inspector 中创建枚举多维数组并使其可序列化 以便我可以从不同的脚本调用它 public enum colors red blue green yellow cyan white purple public in
  • 如何生成可变参数包?

    给定不相关的输入是否可以生成非类型参数包 我的意思是 我想改变这一点 template
  • FFplay成功移入我的Winform中,如何设置它无边框?

    用这个代码 在 C 应用程序中显示 tcp 视频流 来自 FFPLAY FFMPEG https stackoverflow com questions 14201894 show a tcp video stream from ffpla
  • 使用信号和槽更新指针

    我对 Qt 很陌生 请帮我解决这个问题 我正在使用线程在后台执行密集操作 同时我想更新 UI 所以我使用 SIGNALS 和 SLOTS 为了更新 UI 我发出一个信号并更新 UI 让我们考虑下面的示例代码 struct sample QS
  • C++ 模板参数数量错误(2,应该是 1)

    我使用 C 并行快速排序程序进行了测试 如下所示 首先使用列表作为容器 然后我转移到通用容器类型 但它报告了标题错误 可以帮忙解决这个问题吗 include
  • 快速将文本附加到文本框

    我有一个BackgroundWorker正在发布消息的线程 使用BeginInvoke在 GUI 中的文本框中 方法 write debug text 在文本框中显示文本使用AppendText并将文本写入Console 外观上是这样的Ba
  • C中使用JNI从对象获取对象

    public class Student private People people private Result result private int amount 这是 Java 中类的示例 在C中 我试图获取 学生 中的 人 但失败了
  • 从数据库配置中的连接字符串中删除 SSIS 密码

    我有一个 SSIS 包 它使用 SQL 服务器中的 SSIS 配置表来检索 OLE DB 连接管理器的连接字符串属性 问题是我还需要相同的连接字符串来调用使用实体框架的程序集 我尝试访问连接管理器连接字符串属性 但 SSIS 总是删除密码
  • 从其对象获取结构体字段的名称和类型

    例如 我有一个类似这样的结构 struct Test int i float f char ch 10 我有一个该结构的对象 例如 Test obj 现在 我想以编程方式获取字段名称和类型obj 是否可以 顺便说一句 这是 C 你正在要求C

随机推荐

  • 调试仅生产错误的过程是什么?

    首先我要说的是 我对这个话题非常无知 我什至不知道这个问题是否有客观的答案 如果最终结果是 不 我将删除或投票关闭该帖子 场景如下 我刚刚编写了一个小 Web 服务 它可以在我的机器上运行 它可以在我团队领导的机器上运行 据我所知 它可以在
  • RtsEnable 或 DtrEnable 属性是否发送信号?

    我想知道如果我将这些放入代码中 计算机是否会向设备发送任何类型的信号 SerialPort myport new SerialPort COM1 myport DtrEnable true myport RtsEnable true 我需要
  • 无法在 Mac 上使用 ARC 来使用 respondsToSelector

    当我打电话时respondsToSelector在 ARC 环境中 我收到以下错误消息Automatic Reference Counting Issue No known instance method for selector resp
  • sqlite3:在 Windows 10 上找不到命令 Python 3

    我在Windows 10上安装了Python 3 6 5 我看到 Python Python36 Lib目录中有一个sqlite3文件夹 我将Python PATH 添加到环境变量中 但是 我无法从 Powershell 或 Git Bas
  • 关于C++复制构造函数调用的问题

    我试图找出这两行代码之间的区别 我们得到的 Count 是我们的类名 C1 和 C2 是该类的对象 没有给出如何以及何时声明这些类的信息 Count C2 C1 Statement 1 Count C2 C1 Statement 2 没有提
  • PHP 从函数中获取变量

    function first foreach list as item variable item gt ID item gt title gives varible 10 some text 10 can be replaced with
  • 使用密钥大小小于 2048 的 RSA 安全密钥创建 JWT 令牌时出错

    我在尝试创建时遇到异常JWT https jwt io C Web API 应用程序中的令牌 测试环境 平台 带有 net框架的Windows 10 x64 4 6 1 jwt NuGet 包 System IdentityModel To
  • Vuejs 3 和 Bootstrap 5 模态可重用组件以编程方式显示

    尝试使用 vuejs 3 和可组合 API 创建一个基于 Bootstrap 5 的 半 可重用模态组件 设法让它部分工作 给定 主要是标准 Bootstrap 5 模式 但基于 show 属性添加类 以及正文和页脚中的插槽
  • 出于验证目的迭代方法的参数

    我一直在想 能够做这样的事情会很有用 例如 检查参数是否为空引用并最终抛出异常 这将节省一些输入 并且如果添加了新参数 就不可能忘记添加检查 好吧 除非你算一下 public void Foo string x object y Strea
  • 在运行时获取布局高度和宽度android

    如何获取在 xml 中定义为 fill parent 的高度和宽度的线性布局的宽度和高度 我尝试过 onmeasure 方法 但我不知道为什么它没有给出准确的值 在 oncreate 方法完成之前 我需要在 Activity 中使用这些值
  • 训练误差和测试误差相差多少才被认为是合适的? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在研究回归问题 我使用 ad boost 和决策树进行回归 并使用 r 2 作为评估指标 我想知道训练 r 2 和测试 r 2 之间的差异有
  • 解析 Roslyn 中的参数类型

    我正在使用 Roslyn 来实现自定义业务规则 目前 我有点卡住了 我必须在调用方法时验证参数的类型 验证该方法正在被调用或包含参数时没有问题 我已经通过使用 GetSymbolInfo 来获取当前语法的符号来解析 IdentifierNa
  • 获取“sed 错误 - 非法字节序列”(在 bash 中)[重复]

    这个问题在这里已经有答案了 进行一些流编辑以更改令人讨厌的 Parallels 图标 它的开发很差 并且嵌入到应用程序本身中 而不是作为图像文件 所以我找到了这个 sed 命令 它有一些很好的反馈 sudo sed i bak s Para
  • Python:检查负数

    我试图向该字符串添加一段代码以检查第一个位置是否有负数 如果代码识别出负数 则应返回 False 我在用户输入命令中遇到 int 和 str 问题 抱歉 Python 新手 def is number S if s lt 0 print F
  • grails 2.3.4 与 Angular js 结合的智能文件夹结构

    在不使用 grails angularjs 插件的情况下 grails 2 3 4 与 angularjs 结合的智能文件夹结构是什么 目前我已将所有内容打包到webapp folder 组织目录的方法有很多 但是 我们使用的方式 我将其称
  • 如何禁用和启用 android ScrollView 上的滚动? [复制]

    这个问题在这里已经有答案了 我是一名android开发人员 我也想使用ScrollView 这个ScrollView需要一段时间禁用滚动 一段时间启用滚动 但是我无法禁用滚动 如何实现它 请帮助我 我还尝试使用一些代码 例如 s fullp
  • 在循环期间删除列表中的项目

    我有下面的代码 我正在尝试从列表中删除两个字符串predict strings and test strings如果其中一个已在另一个中找到 问题是我必须将它们分开并检查另一个字符串中是否存在一个字符串的 部分 如果存在 那么我只是说存在匹
  • Matlabpool打开worker非常慢

    我刚刚组装了一个新设备 i7 4770K 512gb SSD 16gb DDR3 2133 mhz ram 并安装了 MATLAB r2013a 当我调用 matlabpool 命令时 需要花费很长时间才能打开每个单独的工作线程 您在任务管
  • ruby 中的数据库连接池

    我刚刚开始使用 Ruby 正在使用 Sinatra 但找不到在请求之间共享数据库连接的方法 我来自 Java Web 开发 你必须做的基本事情之一就是池化数据库连接 所以我确信 Ruby 中存在类似的东西 但我只是找不到它 ActiveRe
  • C# 无法使“notnull”类型可为空

    我正在尝试创建一个类似于 Rust 的类型Result或哈斯克尔的Either到目前为止我已经做到了 public struct Result