相关问题:Accessing a Class property without using dot operator
我创建了一个名为MyDouble
的类,如下所示
class MyDouble
{
double value;
//overloaded operators and methods
}
我可以在MyDouble上进行各种操作。例子:
MyDouble a = 5.0;
a += 3.0;
...etc
然而,这仍然会引发错误
MyDouble a = 5.0;
long b = (Int64)a; //error
long b = (int64)a.value; //works
如何定义,(Int64)a
之类的操作会自动转换为(Int64)a.value
?我不希望用户不必担心value
属性的存在。
答案 0 :(得分:9)
为了使此转换有效,您需要explicit conversion到Int64。
这看起来像是:
class MyDouble
{
double value;
public static explicit operator Int64(MyDouble value)
{
return (Int64)value.value;
}
}
答案 1 :(得分:1)
显式从double转换为Int64,但不是从您的类转换为Int64。你需要做的就是定义一个。或者,如果您的班级转换为双倍,我认为您可以这样做,您可以这样做:
长x =(长)(双)a;
然而,这很麻烦;我定义了显式转换运算符。
转换应该是明确的,而不是隐含的,除非您有充分的理由将其明确化。
语言定义的从double到long的转换是显式,因为转换可能会导致信息丢失。您可能会因此转换而丢失信息,因为有一些双打,例如0.5,不能完全转换为long。这称为缩小转换。
使用语言定义的转化,缩小转化是明确的。如果它们是隐含的,程序员可能会通过将一种类型的值分配给另一种类型的变量而意外丢失信息。将此转换定义为隐含违反了完全合理的原则,因此必须有一些令人信服的理由。
这是一个显示这个原则的价值的例子。如果缩小转换是隐含的,则会使代码更加脆弱。假设double-int转换是隐式的:
class Family
{
ICollection<Person> Children { get; set; }
}
int GetAverageNumberOfChildren(IEnumerable<Family> families)
{
return families.Sum(f => f.Children.Count) / families.Count();
}
void SomeMethod(IEnumerable<Family> families)
{
int averageNumberOfChildren = GetAverageNumberOfChildren(families);
//...
}
糟糕!我们有一个错误! GetAverageNumberOfChildren
应该返回双倍!我们来解决它!
double GetAverageNumberOfChildren(IEnumerable<Family> families)
{
return families.Average(f => f.Children.Count);
}
哇,一切都编译并运行!很高兴我们抓住了那个虫子!
但是,遗憾的是,没有。 我们仍有错误! SomeMethod
隐式将double转换为int,因此预期值可能为2.4
,实际值为2
。< / p>
因为double-int转换是显式,所以编译器将我们从自己身上拯救出来。修复GetAverageNumberOfChildren
后,错误的程序无法编译。
现在,如果您的MyDouble
类进行了一些验证,将其限制为范围等于或小于long
范围的整数值,那么您可以安全地隐式转换。但在这种情况下,您当然应该使用long
,而不是double
。
答案 2 :(得分:1)
隐式转换既可以使用也可以进行显式转换。
public static implicit operator long(MyDouble m)
{
return (long) m.value;
}
有了这个,你可以做到:
long b = (Int64) a;
或只是
long b = a;
这只是为了说明转换不需要明确。但是,如上所述,由于数据丢失的可能性, 应该是明确的。