小编Ami*_*tal的帖子

为什么C#允许*Long隐式*从Long转换为Float,这可能会失去精度?

一个类似的问题Long in Float,为什么?这里没有回答我在寻找的东西.

C#标准允许从long到float的隐式转换.但任何长于2 ^ 24的长度在表示为浮动时必然会失去其"价值".C#标准清楚地表明,长期浮动转换可能会失去"精确度",但永远不会失去"幅度".

我的问题是
  1. 关于积分类型,"精确"和"幅度"的含义.数字n与数字n + 1完全不同,与实数不同,其中3.333333和3.333329可能被认为足够接近计算(即取决于程序员想要的精度)
  2. 不允许隐式转换从long到浮动邀请到微妙的错误,因为它可能导致长期"默默地"失去价值(作为一个C#程序员,我习惯于编译器在防范这些问题方面做得非常出色)

那么C#语言设计团队允许这种转换是隐含的理由是什么呢?我在这里失踪的是什么证明从长期到浮动的隐性转换是正确的?

.net c# floating-point implicit-conversion long-integer

20
推荐指数
2
解决办法
3489
查看次数

编译器为delegate关键字生成的密封类包含虚拟方法

delegate关键字在C#所使用的,C#编译器自动生成从派生的类System.MulticastDelegate的类.

这个编译器生成的类也包含3个方法:Invoke, BeginInvoke and EndInvoke.

所有这三种方法都有标记,public virtual extern但有趣的是,类本身已被标记sealed.

在密封类中定义的虚拟方法不仅违反直觉,而且在C#中实际上是非法的.

所以我的问题是,是否有一个特定的原因,或者它只是其中一个无害的事情,记住一些假设的未来增强?

编辑1:

可能的原因是强制使用'callVirt'IL操作码而不是'call',以便在尝试执行这三种方法中的任何一种之前,CLR始终检查委托对象为空?虽然我不明白为什么delegate在这方面应该是一个特例.

也不是强制使用的性能打击callvirt(虽然它可能是微不足道的)

编辑2:

添加了CIL标记,因为事实证明定义委托的C#方式实际上是由CIL标准强制执行的.标准规定(以下不是全文)

代理应具有System.Delegate的基本类型.代表应宣布密封,代表的唯一成员应为此处规定的前两种或全部四种方法.这些方法应声明为运行时和管理.它们不应具有身体,因为该身体应由VES自动创建.委托上可用的其他方法继承自基类库中的System.Delegate类.委托方法是:

  1. 实例构造函数
  2. Invoke方法应该是虚拟的
  3. BeginInvoke方法(如果存在)应为虚拟方法
  4. EndInvoke方法应该是虚拟的

所以这绝对不是编译器进程的副作用,或者类似于其他有趣的编译器输出.

如果标准强调某些东西,那必须是出于某种充分的理由和理由.

所以现在的问题是为什么代表们的CIL标准同时强调密封和虚拟?

渔获物在这里吗?:

它们不应具有身体,因为该身体应由VES自动创建.

它们是否标记为虚拟,以便在调用这些方法时可以执行VES/CLR生成的主体?

.net c# il delegates cil

18
推荐指数
2
解决办法
1980
查看次数