为什么/何时将运算符指定为显式很重要?

2024-05-01

我借用了下面的代码另一个问题 https://stackoverflow.com/a/7305947/93394(稍作修改),在我的代码中使用:

internal class PositiveDouble 
{
      private double _value;
      public PositiveDouble(double val) 
      {
          if (val < 0)
              throw new ArgumentOutOfRangeException("Value needs to be positive");
          _value = val;
      }

      // This conversion is safe, we can make it implicit
      public static implicit operator double(PositiveDouble d)
      {
          return d._value;
      }
      // This conversion is not always safe, so we're supposed to make it explicit
      public static explicit operator PositiveDouble(double d)
      {
          return new PositiveDouble(d); // this constructor might throw exception
      }
}

该代码的原作者正确地遵守了 MSDN 中给出的警告implicit http://msdn.microsoft.com/en-us/library/z5z9kes2.aspx & explicit http://msdn.microsoft.com/en-us/library/xhbhezf4.aspx文档,但这是我的问题:Is explicit在潜在的异常代码中总是必要的?

因此,我的代码中有一些从 PositiveDouble 派生的类型(例如“Volume”),我希望能够像下面的第一行一样方便地设置实例:

Volume v = 10; //only allowed by implicit conversion
Volume v = new Volume(10)  //required by explicit conversion, but gets messy quick

被迫在任何地方都使用显式转换会使代码的可读性大大降低。它如何保护用户?在我的程序的语义中,我从不期望 Volume 为负数;事实上,如果发生这种情况,我预计会抛出异常。因此,如果我使用隐式转换并抛出异常,什么“意外结果”可能会困扰我?


C# 语言规范在 10.10.3 转换运算符下规定:

如果用户定义的转换可能会导致异常(例如,因为源参数超出范围)或信息丢失(例如丢弃高位),则该转换should被定义为显式转换。

另外,从MSDN:隐式(C# 参考) http://msdn.microsoft.com/en-us/library/z5z9kes2.aspx:

一般来说,隐式转换运算符不应该抛出异常,也不应该丢失信息,以便在程序员不知情的情况下可以安全地使用它们。如果转换运算符不能满足这些条件,则它should被标记为明确的。

考虑到这一点,您的operator PositiveDouble(double d) 不应该被标记implicit, as Volume v = -1会抛出异常。

所以回答你的问题:

在潜在的异常代码中显式总是必要的吗?

不,没有必要,但是它should.

基于意见的边界:如果您的代码是唯一使用此转换的代码,并且您发现隐式转换更易于阅读和/或维护,请随意使用它。

As for

它如何保护用户?

See MSDN:显式(C# 参考) http://msdn.microsoft.com/en-us/library/xhbhezf4.aspx提到:

如果转换操作可能导致异常或丢失信息,则应将其标记为显式。这可以防止编译器默默地调用转换操作,从而可能产生不可预见的后果。

我无法真正理解这种情况何时会发生,但同样,如果您认为您永远不会在代码中的任何地方从负双精度转换,那么这不应该抛出。

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

为什么/何时将运算符指定为显式很重要? 的相关文章

  • 金特 + XNA (C#)

    是否可以使用jint http jint codeplex com操作使用 XNA C 创建的 3D 环境 并向该环境添加功能 再次使用 jint 作为 Jint 的贡献者 我会推荐你Jint http jint codeplex com
  • 如何使用 ASP.NET MVC 编辑多选列表?

    我想编辑一个如下所示的对象 我希望用 UsersGrossList 中的一个或多个用户填充 UsersSelectedList 使用 mvc 中的标准编辑视图 我只得到映射的字符串和布尔值 下面未显示 我在 google 上找到的许多示例都
  • c# 从另一个类中的另一个静态事件引发事件

    需要帮助从另一个班级调用事件 我有已声明事件的课程 public class MxPBaseGridView GridView public event AddNewItemsToPopUpMenuEventHandler AddNewIt
  • 锁定 ASP.NET 应用程序变量

    我在 ASP NET 应用程序中使用第三方 Web 服务 对第 3 方 Web 服务的调用必须同步 但 ASP NET 显然是多线程的 并且可能会发出多个页面请求 从而导致对第 3 方 Web 服务的同时调用 对 Web 服务的调用封装在自
  • 进程退出后 POSIX 名称信号量不会释放

    我正在尝试使用 POSIX 命名信号量进行跨进程同步 我注意到进程死亡或退出后 信号量仍然被系统打开 在进程 打开它 死亡或退出后是否有办法使其关闭 释放 早期的讨论在这里 当将信号量递减至零的进程崩溃时 如何恢复信号量 https sta
  • MFC CList 支持复制分配吗?

    我在 MSVC 中查找了 CList 定义afxtempl h http www cppdoc com example mfc classdoc MFC AFXTEMPL H html并记录在MSDN http msdn microsoft
  • 将 OpenCV Mat 转换为数组(可能是 NSArray)

    我的 C C 技能很生疏 OpenCV 的文档也相当晦涩难懂 有没有办法获得cv Mat data属性转换为数组 NSArray 我想将其序列化为 JSON 我知道我可以使用 FileStorage 实用程序转换为 YAML XML 但这不
  • 为什么需要数字后缀?

    C 语言 我确信还有其他语言 需要在数字文字末尾添加后缀 这些后缀指示文字的类型 例如 5m是一个小数 5f是一个浮点数 我的问题是 这些后缀真的有必要吗 或者是否可以从上下文中推断出文字的类型 例如 代码decimal d 5 0应该推断
  • 使用 C# 中的 Google 地图 API 和 SSIS 包获取行驶距离

    更新 找到了谷歌距离矩阵并尝试相应地修改我的代码 我在这里收到无效参数错误 return new GeoLocation dstnc uri ToString catch return new GeoLocation 0 0 https 基
  • 时间:2019-03-17 标签:c++fstream并发访问

    如果从不同的进程 线程同时访问文件会发生什么 据我所知 没有锁定文件的标准方法 只有操作系统特定的功能 就我而言 文件将被经常读取而很少写入 现在如果A打开一个文件进行读取 ifstream 并开始读取块 和B打开相同的文件进行写入 ofs
  • Resharper:IEnumerable 的可能多重枚举

    我正在使用新的 Resharper 版本 6 在我的代码中的几个地方 它给一些文本加了下划线 并警告我可能存在IEnumerable 可能的多重枚举 我理解这意味着什么 并在适当的情况下采纳了建议 但在某些情况下 我不确定这实际上是一个大问
  • 为什么不能调用带有 auto& 参数的 const mutable lambda?

    include
  • C++ 到 C# 事件处理

    所以我有我的C WinForm 应用程序 我从中调用我的C CLI MFC dll图书馆 但也有一些events在我的 C 库上 甚至此事件也发生在该库的本机 非 CLI 部分 我需要从我的 C 应用程序调用一些代码 并获取一些有关此事件的
  • 使用多线程进行矩阵乘法?

    我应该使用线程将两个矩阵相乘 有两件事 当我运行程序时 我不断得到 0 我还收到消息错误 对于每个错误 它在粗体行上显示 警告 从不兼容的指针类型传递 printMatrix 的参数1 我尝试打印输出 还要注意 第一个粗体块 这是我解决问题
  • ALTER TABLE ... ADD CONSTRAINT 失败时将事务回滚到保存点

    有没有办法在事务中添加检查约束and如果失败回滚到以前的保存点 而不是回滚整个事务 就我而言 当 ALTER TABLE ADD CONSTRAINT 命令失败时 事务无法回滚到保存点 尝试这样做会引发 InvalidOperationEx
  • C# 中的 C/C++ 代码编译器

    在 C 中 我可以使用下面的代码编译 VB 和 C 代码 但无法编译 C C 代码 有什么办法可以做到这一点吗 C 编译器 public void Compile string ToCompile string Result null st
  • Autoconf 问题:“错误:C 编译器无法创建可执行文件”

    我正在尝试使用 GNU 自动工具构建一个用 C 编写的程序 但显然我设置错误 因为当configure运行 它吐出 configure error C compiler cannot create executables 如果我看进去con
  • C 语言中的 Alpha 混合 2 RGBA 颜色[重复]

    这个问题在这里已经有答案了 可能的重复 如何快速进行阿尔法混合 https stackoverflow com questions 1102692 how to do alpha blend fast 对 2 个 RGBA 整数 颜色进行
  • 如果“嵌入式”SQL 2008 数据库文件不存在,如何创建它?

    我使用 C ADO Net 和在 Server Management Studio 中创建的嵌入式 MS SQL 2008 数据库文件 附加到 MS SQL 2008 Express 创建了一个数据库应用程序 有人可以向我指出一个资源 该资
  • 嵌入式二进制资源 - 如何枚举嵌入的图像文件?

    我按照中的说明进行操作这本书 http www apress com book view 9781430225492 关于资源等的章节 我不太明白的是 如何替换它 images Add new BitmapImage new Uri Ima

随机推荐

  • 在 Ruby 中,有没有办法重载初始化构造函数?

    在 Java 中你可以重载构造函数 public Person String name this name name public Person String firstName String lastName this firstName
  • 如何在 Gradle 构建中使用 S3 支持的 Maven 存储库的默认 AWS 凭证链?

    根据Gradle 文档 https docs gradle org 2 4 userguide dependency management html 示例 50 27 我们可以将 S3 支持的 Maven 存储库与 Gradle 2 4 一
  • 收到不明确符号的错误,需要帮助来删除它

    我收到此错误 无法在 Visual Studio 2010 中删除 我正在使用一个第三方库 该库使用自己的 字符串 定义 另外 Visual Studio 的 xstring 文件位于其安装的文件夹中 现在 当我尝试编译代码时 出现以下错误
  • 如何阻止诱变剂自动更新 ID3 版本?

    当我尝试在 MP3 中嵌入专辑封面时 诱变剂将 ID3 标签更新为版本 2 4 我不希望这样做 因为在 ID3v2 4 中 我的手机 运行 Windows Phone 8 和我的计算机无法识别标签 显然 只需更改mutagen id3 ve
  • 在 __device/global__ CUDA 内核中动态分配内存

    根据CUDA 编程指南 http developer download nvidia com compute cuda 3 2 prod toolkit docs CUDA C Programming Guide pdf 第 122 页 可
  • 如何根据文件位置运行钩子

    我参与了使用选项卡的 python 项目 但是我没有在我编写的所有其他代码中使用它们 在该特定项目中使用它们至关重要 项目位于特定目录下的一个目录中 IE main folder project1 project2 project3 etc
  • 如何使用相同的可变借用调用 serde_json::to_writer 两次?

    我正在尝试编写一个调用的函数serde json to writer https docs serde rs serde json ser fn to writer html两次写两件事 但我不知道如何写 这是一次尝试 extern cra
  • 我不断听说 DLL 地狱——这是什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何向 Sass 添加自定义函数(通过 Sass::Script::Functions)?

    我使用的是 vanilla Sass 没有 Compass SUZY Bourbon etc 但我无法确定将 rb 文件放在哪里 我不是 Ruby 程序员 但我确实找到了一个别人编写的函数可以满足我的需要 我尝试过搜索 但得到的结果是死胡同
  • 展平 JavaScript 对象数组

    我有一个具有层次结构的对象数组 如下所示 name ParentOne children name ParentOneChildOne name ParentOneChildTwo children name ParentOneChildT
  • 在cmake中检测项目语言

    我想检测当前的项目语言 例如 如果我有这样的东西 cmake minimum required VERSION 3 0 project foo VERSION 1 0 LANGUAGES CXX 我需要这样的东西 if project la
  • 如何处理会减慢构建和 IDE 速度的巨大 efcore 迁移设计器文件

    我目前有一个 efcore 2 1 项目 包含大约 230 个实体和大约 350 个迁移 每次我添加 efcore 迁移时 都会创建一个设计器文件 该文件大约 535 kb 并且不断增长 所有设计器文件总共 150mb 这使得 IDE 缓慢
  • 如何在 XAML 中自动调整列表视图的高度

    我的列表视图对象接收图像 ID 号和概要 概要的大小各不相同 因为有些有空格返回 我注意到 ListView 有一个可以设置的行高 我现在设置为 250 但它只能是一个固定值 那么会发生什么 我的网格对于 ListView 来说变得太大 导
  • 判断一个点是否在多面体内部

    我试图确定某个特定点是否位于多面体内部 在我当前的实现中 我正在研究的方法采用我们正在寻找多面体面的数组 在本例中为三角形 但稍后可能是其他多边形 的点 我一直在尝试根据这里找到的信息进行工作 http softsurfer com Arc
  • 使用 lodash 按值(整数)对数组进行排序

    我真的很挣扎 但我找不到解决方案 我有一个数组 我想按值 所有整数 对其进行排序 我想 好吧 让我们使用 lodash 肯定有一个方便的功能 不知怎的 我不知道该怎么做 到目前为止我得到了这个 myArray 3 4 2 9 4 2 如果我
  • BI Publisher 和 Excel 模板预览错误

    我正在使用 Excel 2013 并添加了 BI 发布器 我加载示例数据 并进行预览 我得到以下内容 请指教 谢谢詹姆斯 启动 Excel 预览 仅开放 false mTemplate C Users AJCENTROID AppData
  • 非通用接口是通用接口的同义词

    我在 C 中有一个通用接口 并且几乎总是将它与其中一种类型一起使用 我想为该类型创建一个非通用接口并使用它 假设我有以下代码 public interface IMyGenericList
  • jquery:卸载还是卸载之前?

    当用户从当前页面导航时 我想向服务器发布一条消息 我现在正在使用 unload 但结果不可靠 即使在其文档中也是如此 卸载事件的准确处理 各个版本都有所不同 浏览器 例如 某些版本 Firefox 的触发事件当 链接已被跟踪 但当 窗口已关
  • 是 F# 映射上的迭代还是集合中序遍历?

    AFAIK F Map 和 set 被实现为红黑树 所以我猜这些的迭代将是有序遍历 我做了一些测试 迭代结果总是排序的 但我想确定一下 是按顺序遍历吗 MSDN 上的文档非常适合解决这个问题 例如 返回值Set toSeq http msd
  • 为什么/何时将运算符指定为显式很重要?

    我借用了下面的代码另一个问题 https stackoverflow com a 7305947 93394 稍作修改 在我的代码中使用 internal class PositiveDouble private double value