mogmo .NET

C#/XAML/VB6たまにC++についてメモ程度に書いていく。あくまで自分用。責任は取れません。

型変換演算子 implicit/explicit operator

変換演算子は,ユーザが定義したクラス型を別の型に変換するもの。

構文

暗黙的と明示的の2種類の構文がある。

  • 暗黙的(implicit)

別の型に変換した時に,自動的に変換演算子が呼び出される。

public static implicit operator 変換後の型(変換元の型 値1) { return2 } 
  • 明示的(explicit)

明示的に変換を行ったときに,変換演算子が呼び出される。

public static explicit operator 変換後の型(変換元の型 値1) { return2 } 

用語を言語別に管理するクラスを用意して,文字列に変換する処理を行う例を使う。

用語管理クラス:

public class LanguageManager
{
  private string _japanese;
  private string _english;
    
  public LanguageManager(string japanese, string english)
  {
    _japanese = japanese;
    _english = english;
  }

  public static implicit operator string(LanguageManager label)
  {
    if ((CultureInfo.CurrentCulture.Name == "ja-JP") && (label._japanese != null))
    {
      return label._japanese;
    }
    return label._english;
  }
}

暗黙的(implicit)変換演算子

暗黙的に変換演算子が呼び出される例を示す。
コンストラクタで_labelsにデータベースとなる文字列を登録していて,
GetLabelメソッドが呼び出された時,LanguageManagerからstringを返すと言う処理にしている。

Client側のコードの全文:

public class Main
{
  private List<LanguageManager> _labels;

  public Main()
  {
    _labels = new List<LanguageManager>();
    _labels.Add(new LanguageManager("佐藤", "Sato"));
    _labels.Add(new LanguageManager("田中", "Tanaka"));
  }

  public string GetLabel(int index)
  {
    if (index >= _labels.Count) return "";

    string label = _labels[index]; // ← 暗黙的(implicit)変換演算子
    return label;
  }
}

明示的(explicit)変換演算子

明示的変換演算子を使う場合は,クライアント側では明示的キャストを行う必要がある。

string label = _labels[index]; // エラー
string label = (string)_labels[index]; // 明示的変換演算子

制限

  • 以下に示す変換を定義/再定義することはできない。
    • 組み込み型→組み込み型(例:double → int)
    • object → object
    • 基本クラス ⇔ 派生クラス
    • インターフェース ⇔ ***
  • 特定の変換元と変換後の組み合わせに対して,暗黙的と明示的の両方を定義することはできない

暗黙的と明示的をどう使い分けるか

以下の条件を満たさない場合は,明示的を定義すべき。

  • 情報が失われない(例:オーバフローや符号が失われたりしない)
  • 変換時に例外が発生しない

参考

ハーバート・シルト著 「独習C# 第3版」