使用隐式/显式转换而不是构造函数的原因是什么?
一个例子是:
XNamespace ns = "my namespace"
为什么不?:
XNamespace ns = new XNamespace ( "my namespace" )
使用隐式/显式转换而不是构造函数背后的想法是什么?方便?
有这方面的指南吗?
An example would be:
XNamespace ns = "my namespace"
Why not?:
XNamespace ns = new XNamespace ( "my namespace" )
What's the idea behind using implicit/explicit convertions instead of constructors? Convenience?
Is there a guideline for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
或多或少,是的。考虑这样的情况:您有一个类似数字的对象(例如,
Complex
)要对其进行计算。显然,编写如下代码是非常烦人且难以阅读的。隐式转换在这里很有帮助(在本例中,另一种选择是运算符重载,但这会导致许多类似的重载)。
提供尽可能少的隐式转换,因为它们可能隐藏问题。隐式转换在增加简洁性的同时,也降低了明确性。有时这很好,但有时则不然。
我发现最好将隐式转换限制为非常类似的类型,例如上面示例中的类似数字的对象:
int
本质上是一个Complex< /code> (从数学的角度来看;即使它不是通过继承建模的),因此隐式转换是有意义的。
在 VB 中,隐式转换称为“
加宽
”(与缩小
相反,后者是显式
),这很好地描述了它:无信息在转换过程中丢失。此外,运算符本质上是一个构建器函数,并且具有构建器函数相对于构造函数的(一些)常见优点:即,它可以重用缓存的值,而不是总是创建新实例。
考虑我的
复杂
示例。我们可能想要缓存常用的复数的值:当然,这种微优化是否有效是另一个问题。
More or less, yes. Consider the case for when you’ve got a number-like object (say, a
Complex
) on which you do calculations. Clearly, writing code such as:is very annoying and hard to read. Implicit conversions help here (an alternative would be operator overloads in this example, but that would lead to lots of similar overloads).
Provide as few implicit conversions as possible, since they may hide problems. Implicit conversion reduce explicitness by the same amount by which they increase terseness. Sometimes this is good, but sometimes not.
I find it best to restrict implicit conversions to very similar types, such as the number-like objects in my example above: an
int
essentially is-aComplex
(from a mathematical standpoint; even if it’s not modelled via inheritance), hence an implicit conversion makes sense.In VB, an implicit conversion is called “
Widening
” (as opposed toNarrowing
, which isexplicit
) and this describes it well: no information is lost in the course of the conversion.Furthermore, an operator is essentially a builder function, and has (some of) the usual advantages of a builder function over a constructor: namely, it can re-use cached values instead of always creating new instances.
Consider my
Complex
example. We may want to cache values for often-used Complex numbers:Of course, whether this micro-optimization is effective is another question.
我认为,使用 XName 等简单类型的隐式转换的原因之一是调用方法的便利性。
例如,您可以
在提取数据时编写简单性,这就是 LINQ 的全部内容,如果我们
甚至必须为最简单的查询编写,那么对于复杂的查询,LINQ 是否完全值得?
这里的另一个重要问题是 XName 是原子化的。
请参阅 MSDN:
您无法在构造函数中提供原子化,但是定义转换允许您从池中选择相应的对象并将其返回,就像它是一个新实例一样。
One of the reasons behind using implicit conversion with such simple types as XName is, I believe, convenience in calling methods.
For example, you can write
Simplicity at extracting data is what LINQ is all about, and if we had to write
even for simplest queries, would LINQ be totally worth it for complex ones?
Another important issue here is that XNames are atomized.
See MSDN:
You can't provide atomization in constructor, but defining a conversion allows you to pick corresponding object from the pool and return it as if it were a new instance.
使用隐式/显式转换是为了方便,许多编程指南建议您避免使用隐式/显式转换,而转而使用显式
ConvertToXXX
方法。问题之一是使用隐式/显式转换进一步重载了强制转换运算符的函数。它赋予它双重目的:
不幸的是,C# 已经在其他领域(使用基元和装箱)实现了后者。
The use of implicit / explicit conversions is issue of convenience and one that many programming guidelines suggest you avoid in favor of explicit
ConvertToXXX
methods.One of the problems is tha the use of implicit / explicit conversions further overloads functions of the casting operator. It gives it the dual purpose of
Unfortunately C# already does the latter in other areas (with primitives and boxing).
如果两个类应该可以相互转换,但它们不共享自动允许这种行为的基类接口,则您将使用转换。隐式转换永远不应该有数据丢失的可能性;它们通常被认为是“扩大”转换。例如,将
int
转换为long
是一种加宽转换,并且隐式转换本身不存在问题。显式转换可能会导致数据丢失;long
可能会也可能不会转换为int
,具体取决于它的值。我在隐式转换中使用的一个技巧是,当我没有其他合理的选择时,将不同名称空间中的类相互转换。例如,一个 WCF 服务返回一个 AuthenticationToken 对象,我需要将其传递给不同命名空间中的 WCF 服务。两者都有这个 AuthenticationToken 对象,不断的转换会很痛苦。我的解决方案涉及在分部类中使用公共静态隐式运算符来添加转换每种方式的功能。
If two classes should be convertible to one another, but they do not share an interface of a base class that allows this behavior automatically, you would use the conversions. Implicit conversions should never have a possibility of data loss; they are often considered "widening" conversions. For example, converting an
int
to along
is a widening conversion, and there is no problem inherent in the conversion being implicit. Explicit conversions may involve the possibility of data loss; along
may or may not be convertible to anint
, depending on its value.One trick I have used with implicit conversions is to convert classes in different namespaces to each other when I did not have another reasonable option. For example, one WCF service returns an AuthenticationToken object that I need to pass to a WCF service in a different namespace. Both have this AuthenticationToken object, and constant conversion would have been a pain. My solution involved using
public static implicit operator
in a partial class to add the functionality to convert each way.就我个人而言,当我知道 rhs 可以转换为类的静态成员时,我会使用转换(例如说
color = "red"
暗示color = Colors.Red
)当我打算实际创建一个新实例时,我使用 new 运算符。
Personally, I use the conversions when I know that the rhs may be converted into a static member of a class (like saying
color = "red"
to implycolor = Colors.Red
)I use the new operator when I intend to actually create a new instance.