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

カスタムキャストは変装した関数です。実際のキャストが実行されるか、カスタム変換演算子が呼び出されるかは、キャストされる式のコンパイル時の型によって異なります。

あなたの例では、キャストされる式のコンパイル時の型です。式の型は、b文字列へのカスタム変換を持たないobject型です。objectただし、キャスト有効な場合があるため、コンパイラによって許可されます。

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

4 行目は // カスタム変換文字列として定義された関数を呼び出す d = MyString.op_implicit(a); として扱われます。

5行目も同様です。5 行目はキャストの構文を使用していますが、キャストではなく変換です。

ただし、3行目はキャストのように見え、キャストです。キャストとは、オブジェクトの実行時の型に関して、コンパイルよりも多くの情報があることをコンパイラに伝えることです。(string)aa で表されるオブジェクトが文字列の実行時型を持つことを保証できることをコンパイラに伝えます。あなたの場合、それは真実ではMyStringありませんが、文字列から派生していない型を持っています(文字列が封印されているのでできません)。

要点は、カスタム変換 (暗黙的または明示的のいずれかを使用して定義) はキャストと同じ構文を持っていますが、それらはキャストとはまったく異なるものであるということです。キャストは継承チェーン (インターフェイスの継承を含む) を離れることはありません。キャストを使用してチェーンを上または下に移動できますが、決して離れることはありません。

于 2012-07-31T11:14:03.530 に答える
2

最後の行を次のように変更してみてください。

string c = (string)((MyString)b);
于 2012-07-31T11:06:33.650 に答える
-1

試してみてください :

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