Effective C# Item 28: Avoid Conversion Operators
转换操作为我们提供了类之间的一种可置换的关系。这意味着一个类的对象可以被其它类的对象替代。这样的好处在于:一个派生类的对象可以被其基类的对象代替。我们可以参考下图结构。我们创建一个Shape基类和三个派生类:Circle,Ellipse,Square。任何情况下都可以用Circle来替代Shape,因为Circle是一个特殊的Shape,这是多态的表现。就像在.Net中,任何对象都可以被System.Object型的对象替代,它是所有类型的基类。同样,我们自己创建的类的对象也可能被实现同样接口的类、实现同样基类接口的类或者基类的对象替代。
如果我们需要为类定义转换操作,就说明它可能会被其它的目标类型所替换。这种替换经常会引发一些潜在的错误,往往是因为两个类型之间的转换并不完美造成的。另外,在效率方面,修改目标类型的操作效率往往较低,特别是当转换产生临时对象的时候。而且,转换操作的规则基于编译期的类型对象发挥作用,而不是运行期。用户可能会需要使用多种强制类型转换来实现这种替代关系,这可能会造成代码难以维护。
如果确实需要将一个类型转换为另一个目标类型,我们应当通过构造函数来实现。这样会使我们创建新对象的操作更加清晰。使用隐式转换往往会造成一些难以发现的错误。假设我们有如图中的类结构。从基类中派生出三个子类。我们知道每个圆都是一个椭圆,另外一些特殊的椭圆是圆。虽然圆和椭圆之间是有关系的,但是我们还是将结构设计成这样,这是因为我们不希望在结构中有非抽象的叶子类(否则这里的结构应该是hape->Ellipse->Circle)。由于每个圆都是椭圆,那么我们可以添加一个由圆创建一个新的椭圆的转换:
class Circle : Shape
{
private PointF _center;
private float _radius;
public Circle(PointF c, float r)
{
_center = c;
_radius = r;
}
public Circle()
: this(PointF.Empty, 0)
{
}
static public implicit operator Ellipse(Circle c)
{
return new Ellipse(c._center, c._center, c._radius, c._radius);
