字符串转换不起作用

Dee*_*ain 5 c# casting operator-overloading type-conversion

考虑这样一个类:

public class MyString
{
 private string _string;

 public string String
 {
  get { return _string; }
  set { _string = value; }
 }

 public MyString(string s)
 {
  _string = s;
 }

 public static implicit operator string(MyString str)
 {
  return str.String;
 }

 public static implicit operator MyString(string str)
 {
  return new MyString(str);
 }
}
Run Code Online (Sandbox Code Playgroud)

如何使以下代码有效?

MyString a = "test";
object b = a;
var c = (string)b;
Run Code Online (Sandbox Code Playgroud)

现在我得到这个例外:

InvalidCastException:无法将类型为'MyString'的对象强制转换为'System.String'.

Run*_* FS 2

自定义强制转换是一种变相的函数。是否执行实际转换或调用自定义转换运算符取决于所转换表达式的编译时类型。

在您的示例中,正在转换的表达式的编译时类型即。表达式的类型b是没有自定义转换为字符串的object类型。object然而,强制转换可能是有效的,因此是编译器允许的。

MyString a = "test";
object b = a;
var c = (string)b;
string d = a;
var e = (string)a;
Run Code Online (Sandbox Code Playgroud)

第四行将被视为//调用定义为自定义转换字符串的函数 d = MyString.op_implicit(a);

第五行也是同样的情况。第五行尽管它使用强制转换的语法,但它不是强制转换,而是转换。

然而,第三行看起来像一个演员,而且确实是一个演员。强制转换是告诉编译器您比编译器拥有更多有关对象运行时类型的信息。(string)a告诉编译器可以放心,a 表示的对象将具有字符串的运行时类型。在你的情况下,这不是真的,它的类型MyString不是从字符串派生的(并且不能,因为字符串是密封的)。

要点是,尽管自定义转换(使用隐式或显式定义)具有与强制转换相同的语法,但它们与强制转换完全不同。强制转换永远不会离开继承链(包括继承接口),您可以使用强制转换沿链向上或向下移动,但永远不会离开它