我借用了下面的代码另一个问题 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(使用前将#替换为@)