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

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

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

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

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

obj = 123.4; //impl op assignement

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

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

===============>>#1 票数:3

摆脱隐式转换。

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

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

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


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

===============>>#2 票数:3 已采纳

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

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

obj = SomeClass.FromDouble(123.4);

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

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

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

===============>>#3 票数:2

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

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

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).

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

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

  ask by Brady Moritz translate from so

未解决问题?本站智能推荐:

3回复

C#隐式转换运算符和/作为运算符

我正在创建一个复合对象,我希望能够在其中一个包装对象可以使用的任何地方使用它。 因此给出以下对象: 我想通过以下测试: 我看了一下MSDN文档: 是: http : //msdn.microsoft.com/en-us/library/scekt9xw.aspx as:
4回复

为什么“as”运算符不在C#中使用隐式转换运算符?

我在C#(虚拟代码)中定义了从/到某个类型的隐式字符串转换: 在外部库代码的某处, MyType的实例作为object参数传递给方法。 该方法的一部分看起来像这样的东西: 为什么演员不使用隐式转换器? 我认为这些的重点是使铸造和透明使用成为可能吗? 如果MyType有一
1回复

为什么我不能使用带显式运算符的接口? [重复]

这个问题在这里已有答案: 为什么不能从接口到类定义隐式转换运算符? 2个答案 我只是想知道是否有人知道你不允许使用隐式或显式运算符的接口的原因? 例如,这会引发编译时错误: “不允许在接口之间进行用户定义的转换” 谢谢,
1回复

如何在类型中实现DirectCast运算符?

在下面这样的自定义类型中实现CType运算符时,无法使用DirectCast运算符强制转换Type: 另一方面,它可以直接分配给Color对象,这非常令人困惑: 然后,我想实现的DirectCast首先运营商获得在我的环境打字的舒适度(而不是使用的CType ),其次是获得ben
5回复

使用as运算符进行强制转换,即使在使用is运算符后验证C#中的类类型?

我理解使用as运算符来强制转换对象,通常是更理想的,因为如果转换失败,引用变量将变为null而不是抛出异常。 但是,让我说我检查一个对象的类的类型,它是在List内部,之前使用as运算符,像这样, 是否使用as运算符首先通过is运算符检查失去了它的好处? 所以做下面的演员也同样好
1回复

C#为什么必须将转换运算符声明为static和public?

关于以下编译器错误: 用户定义的运算符'Foo.implicit operator Foo(Bar)'必须声明为static和public 这是什么原因? 为什么用户定义的转换运算符必须public ? 提供以下代码,为什么这种转换不合法: 我检查了C#语言规范
2回复

运算符“&”不能应用于类型为“字符串”和“整数”的操作数

我正在将字符串转换为十六进制,然后执行&操作。 这是一个似乎有问题的方案: 在上一行向我抛出错误: Operator '&' cannot be applied to operands of type 'string' and 'int' 这里有什么问题? 我在C
3回复

C#隐式/显式类型转换

我有一个简单的场景,可能会或可能不会。 我有一个包含整数的类,为此我会尽可能简单: 如何使Test()函数正常工作,因为我编写了它? 这甚至可能吗? 我认为这可以使用显式/隐式运算符来完成,但我无法弄明白。
3回复

我可以在C#中实现从字符串到布尔值的隐式“转换”吗?

有什么方法可以使用C#实现从string到bool的隐式转换? 例如,我的字符串str的值为Y ,当我尝试将(转换)为boolean它必须返回true 。
10回复

为什么允许从超类到子类的隐式转换?

有人能告诉我为什么用“// Compiles”编译的行,以及“//不编译”的行为什么不编译? 我不明白为什么A可以隐含地转换为B,而不是相反。 谢谢!