5

考虑这样一个类:

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);
 }
}

如何使以下代码工作?

MyString a = "test";
object b = a;
var c = (string)b;

现在我得到了这个例外:

InvalidCastException:无法将“MyString”类型的对象转换为“System.String”类型。

4

4 回答 4

4

自定义隐式/显式运算符仅在类型值之间起作用 - 而不是object. 这样的转换总是要么是基本的类型检查,要么是取消装箱。隐式转换是:

string s = a;
于 2012-07-31T10:58:10.570 回答
2

您可以尝试将最后一行更改为:

string c = (string)((MyString)b);
于 2012-07-31T11:06:33.650 回答
2

自定义演员表是变相的功能。是执行实际转换还是调用自定义转换运算符取决于被转换表达式的编译时类型。

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

MyString a = "test";
object b = a;
var c = (string)b;
string d = a;
var e = (string)a;

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

第五行也是如此。第五行即使它使用强制转换的语法也不强制转换而是转换。

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

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

于 2012-07-31T11:14:03.530 回答
-1

你应该试试 :

public MyString:String
{
//code
}
于 2012-07-31T11:02:04.840 回答