转换操作符为类之间引入了一种“可替换性”(substitutability)。“可替换性”表示一个类的实例可以替换为另一个类的实例。
public class ClassA
{
}
public class ClassB
{
public static implicit operator toClassA(ClassB classB)
{
return new ClassA();
}
}
在某个类型定义了转换操作符之后,实际上是告诉编译器这些类型可以当做目标类型使用。不过,这样的替换经常会导致一些难以理解的BUG,因为这个类型不能完美的当做目标类型的替代品。
public void SetValue(ClassA classA)
{
classA.Value1 = classA.Vaule2 * 2;
classA.Value2 += 1;
}
//执行SetValue
ClassB classB = new ClassB();
SetValue(classB);
上述代码就会出现问题。SetValue()方法接收一个ClassA
作为参数。因此,编译器通过转换操作把ClassB
创建一个临时ClassA
对象,然后传递给SetValue()当参数。这个临时对象会被SetValue()修改,随后立即变成垃圾对象。结果ClassB
什么都没有发生。
如果希望将一个类型转换成另一个类型,那么最好使用构造函数。这种做法更能清楚的表示出创建对象的行为。
public class ClassA
{
public ClassA(ClassB classB)
{
//code ...
}
}
public class ClassB
{
}
//转换并执行SetValue
ClassB classB = new ClassB();
ClassA classA = new ClassA(classB);
SetValue(classA);
通过使用构造函数来代替转换操作符,不但没有丢失任何功能,反而使得创建工作变动更加清晰。