繁体   English   中英

防止在隐式运算符中覆盖

[英]prevent overwriting in implicit operator

我有一个小类,我们称之为uomvalue,它包含一个UOM和一个Value字段。

我有一个隐式运算符,当直接应用该运算符时,它会将double转换为Value字段。

因此,如果我以“正常”方式使用它,一切都很好:

obj.UOM = "ft"; 
obj.Value = 123.4; //normal assignment

我的问题是,当我使用隐式运算符进行赋值时:

obj = 123.4; //impl op assignement

...整个对象被替换了,我对UOM所做的任何分配都丢失了。

这可能属于“愚蠢的问题”类别,因为我确实没有花任何时间来解决这个问题,但是有一种简单的方法可以做到这一点,即在展示时我可以保留UOM的旧值。 同上 用来?

摆脱隐式转换。

您的隐式强制转换会破坏信息(即UOM字段)。
隐式强制转换应始终将所有信息保留在源对象中。

如果目标类型比源类型窄,请使用显式强制转换。

这就是为什么uint隐式转换为double而不是int


另外,由于您的类型表示一个值,因此它应该是不可变的。

最简单的答案:不要从double隐式转换。 在我看来,这样的隐式转换几乎总是一个坏主意。 (有例外,但听起来不像是例外之一。)

在我看来,隐式转换也更适合不可变类型,在这种情况下,您所描述的情况根本不会发生。 在我看来, 没有隐式转换,您的代码肯定会更清晰。 例如:

obj = SomeClass.FromDouble(123.4);

就其所做的事情而言,现在显而易见。

不,您不能编写试图保留现有值的隐式运算符。 毕竟,转换都发生在赋值之前-表达式123.4任何内容都不了解obj ...,因此您必须使赋值运算符本身知道它应该使用变量值的一部分,该变量用于被指定为工作了分配的值的一部分。 如果事先没有这样的值,那就成问题了。

所有这些都变得越来越复杂:放弃转换:)

我记得一个小学老师,他会在需要时回答任何省略单位的答案,问“什么?绵羊?米?磅?年?”。

您有一个本该具有该问题答案的类,并且隐式运算符将其删除。 如果您这样做:

x = 6.0

您说的是“ x现在等于6.0”。 不是“ x现在等于6.0是数字的那些方面,而在其他方面没有改变”,而是“ x现在等于6.0”

因此,即使您尝试的是可能的,对于显式运算符,也不要介意隐式运算符,这将是一个糟糕的设计。

另一种方式是另一回事。 如果我们这样做:

UnitMeasure um = new UnitMeasure(6.0, Units.Meter);
double d = (double)um;

然后,对于代码的调用者来说,当我们将6.0meters分配给double时,该double现在包含6.0了,这对于代码的调用者来说更为清楚。 我还是要让它显式而不是隐式的(它会丢失信息),并且有些人会足够谨慎地强制使用强制转换来避免它(无论哪种方式都有好的论点),但至少这意味着某些含义。

归根结底,您正在为人类和机器编写代码。 如果您没有写出有意义的东西,或者更糟的是迫使他人写没有意义的东西,那么您的设计可以得到改进,并且“数字和单位等于6的这种组合”是没有意义的。


除此之外,隐式运算符(以及该问题的显式运算符)像它们一样被覆盖的原因在于,这正是它们的用途。 (int)3.2创建一个全新的int (double)76创建一个全新的double。

之间没有区别:

obj = 123.4;

UnitMeasure temp = new UnitMeasure(123.4);
obj = temp;

那怎么不能覆盖obj呢?

不会创建新对象的强制转换的唯一形式是改变对象使用方式而不是对象使用方式的上下转换:

string s = "abc";
object o = s;//implicit - but s was already an object!
string s2 = (string)o;//explicit - but o was already a string! (and it would throw otherwise).

这些形式不会更改对象的某些部分,因为它们不会更改对象的任何部分。

在一天结束时,您要问的是如何具有一个隐式转换,其行为不像隐式转换。 谢天谢地,你不能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM