明确和放大器;隐式操作使用数字类型和放大器;意外的结果 [英] Explicit & Implicit Operator with Numeric Types & unexpected results
问题描述
我从来没有做过任何广泛的工作,重载运营商,尤其是隐性和显性转换。
I have never done any extensive work with overloading operators, especially the implicit and explicit conversions.
不过,我经常使用的几个数值参数,所以我正在创建一个结构作为一个包装围绕一个数字类型强烈键入这些参数。下面是一个例子实现:
However, I have several numeric parameters that are used frequently, so I am creating a struct as a wrapper around a numeric type to strongly type these parameters. Here's an example implementation:
public struct Parameter
{
private Byte _value;
public Byte Value { get { return _value; } }
public Parameter(Byte value)
{
_value = value;
}
// other methods (GetHashCode, Equals, ToString, etc)
public static implicit operator Byte(Parameter value)
{
return value._value;
}
public static implicit operator Parameter(Byte value)
{
return new Parameter(value);
}
public static explicit operator Int16(Parameter value)
{
return value._value;
}
public static explicit operator Parameter(Int16 value)
{
return new Parameter((Byte)value);
}
}
当我与我的测试实现获得试验显性和隐性运营商的窍门,我想明确地蒙上了的Int64
我的参数
键入和我惊讶没有抛出异常,甚至更令人惊讶的,它只是截断的数量并继续前行。我试着不包括自定义明确的运营商,它仍然表现相同。
As i was experimenting with my test implementation to get a hang of the explicit and implicit operators, I tried to explicitly cast a Int64
to my Parameter
type and to my surprised it did not throw an exception, and even more surprising, it just truncated the number and moved on. I tried excluding the custom explicit operator and it still behaved the same.
public void TestCast()
{
try
{
var i = 12000000146;
var p = (Parameter)i;
var d = (Double)p;
Console.WriteLine(i); //Writes 12000000146
Console.WriteLine(p); //Writes 146
Console.WriteLine(d); //Writes 146
}
catch (Exception ex)
{
Console.WriteLine(ex.Message); //Code not reached
}
}
所以我重复我的实验一个普通的字节
代替我的结构,并具有完全相同的行为,所以显然这是预期的行为,但我认为有明确的转换是导致数据丢失的将抛出一个例外。
So I repeated my experiment with a plain Byte
in place of my struct and has the same exact behavior, so obviously this is expected behavior, but I thought an explicit cast that results in a lose of data would throw an exception.
推荐答案
当编译器在分析一个明确的用户定义转换它是允许把转换的两侧(或两者)明确的内置的转换。因此,举例来说,如果你从int到弗雷德有一个用户定义的转换,你有:
When the compiler is analyzing an explicit user-defined conversion it is allowed to put an explicit built-in conversion on "either side" (or both) of the conversion. So, for example, if you have a user-defined conversion from int to Fred, and you have:
int? x = whatever;
Fred f = (Fred)x;
那么编译器的原因没有从int到弗雷德显式转换,这样我就可以做出明确从int转换?为int,然后转换成int值弗雷德。
then the compiler reasons "there is an explicit conversion from int to Fred, so I can make an explicit conversion from int? to int, and then convert int to Fred.
在你的榜样,有一个内置的显式转换,从长到短,且有从短到参数的用户定义的显式转换,所以转换长的参数是合法的。
In your example, there is a built-in explicit conversion from long to short, and there is a user-defined explicit conversion from short to Parameter, so converting long to Parameter is legal.
同样是隐式转换的真实,编译器可以插入内置的隐式转换在用户定义的隐式转换的两侧。
The same is true of implicit conversions; the compiler may insert built-in implicit conversions on either side of a user-defined implicit conversion.
从未链两个用户定义的转换的编译器。
The compiler never chains two user defined conversions.
正确地构建自己的显式转换为C#中的艰巨的任务,我鼓励你停止试图这样做,直到你有覆盖转换规范的整章的全面和深刻的理解。
Building your own explicit conversions correctly is a difficult task in C#, and I encourage you to stop attempting to do so until you have a thorough and deep understanding of the entire chapter of the specification that covers conversions.
有关链接转换的一些有趣的方面,看到我对这个问题的文章:
For some interesting aspects of chained conversions, see my articles on the subject:
的 http://blogs.msdn.com/b/ ericlippert /存档/ 2007/04/16 /链式用户自定义,显式转换功能于c.aspx
的 HTTP://blogs.msdn。 COM / b / ericlippert /存档/ 2007/04/18 /链式用户自定义,显式的转换,在C-部分two.aspx
这篇关于明确和放大器;隐式操作使用数字类型和放大器;意外的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!