HOWTO · Csharp

C# で型エイリアスを定義する

このチュートリアルでは、C# で型エイリアスを定義する方法を説明します。

このページの内容

C# エイリアスを使うと、既存の型に別の名前を付けられます。新しい型が宣言されるわけではなく、型の動作が変わったり、別個の型として扱われたりすることもありません。たとえば、エイリアスを使って宣言した変数も、実際には元の型です。そのため、エイリアスは型安全性を高めるものではなく、読みやすさの向上や名前の曖昧さの解消に役立ちます。

組み込みの仕組みは、using エイリアスディレクティブです。型名が長い場合や、インポートした型どうしで名前が重複する場合に使います。エイリアスはディレクティブを宣言したソースのスコープで有効であり、プロジェクト間で自動的に共有されることはありません。独自の動作や型の識別性が必要なら、継承やラッパーのほうが適している場合があります。

C# エイリアスの仕組み

エイリアスは、型または名前空間に付けるソースコード上の別名です。値をラップしたり、サブクラスを作ったり、通常はアクセスできないメンバーへのアクセスを可能にしたりするものではありません。コンパイラーはエイリアスを参照先の型に解決するため、その型を受け取る API には、エイリアス名で指定した値も渡せます。

設計を選ぶ際には、この違いが重要です。参照を短くしたい場合や、参照先を明確にしたい場合はエイリアスを使います。独自の動作、検証、API コントラクトを持つ別個の概念が必要なら、型を個別に宣言します。

using ディレクティブで型エイリアスを作成する

エイリアスを使う宣言より前に、using エイリアスディレクティブを記述します。たとえば、using Writer = System.IO.StringWriter; のように宣言します。その後は、完全な型名の代わりに Writer を使えます。このディレクティブが有効なのは、宣言したコンパイル単位または名前空間のスコープ内であり、プロジェクト全体で使える名前を作るわけではありません。また、ローカルなエイリアスを使えば、名前空間内のすべての名前をインポートせずに、通常なら曖昧になる型名を明確に指定できます。

次の例を実行してください。

このセクションのコードと表示されるラベルや出力は英語のままです。

using System;
using Writer = System.IO.StringWriter;

class Program
{
    static void Main()
    {
        using (Writer writer = new Writer())
        {
            writer.Write("Alias target: ");
            writer.Write(typeof(Writer).Name);
            Console.WriteLine(writer.ToString());
        }
    }
}

エイリアスは名前を短くしただけのものです。typeof(Writer) が参照するのは System.IO.StringWriter です。using キーワードは、上の using ブロックのようなリソース管理文にも使われています。この別の構文では、制御がブロックを抜けるときにライターが破棄されます。

using ディレクティブで名前空間にエイリアスを付ける

名前空間を参照先にすれば、同じ形式で名前空間エイリアスを作成できます。例: using Drawing = System.Drawing;。この名前空間と型を利用できる場所では、Drawing.Point のように型を参照できます。namespace キーワードは名前空間を宣言するもので、それだけではエイリアスを作成しません。

using System; のように名前空間を通常の方法でインポートすると、その名前空間内の名前を検索時に利用できますが、入れ子になった名前空間が自動的にインポートされるわけではありません。名前空間エイリアスがするのは名前を短くすることだけです。アクセス規則を変えたり、プライベートメンバーへのアクセスを許可したりすることはありません。

別個の型が必要なら継承を使う

継承では、既存の型を基に新しい型を宣言します。たとえば、class NamedList : System.Collections.Generic.List<string> { } は、文字列のリストとして使える独立したクラス NamedList を宣言します。エイリアスとは異なり、宣言された型として独自の識別性があり、メンバーやその他の動作を追加できます。

派生型が意味のあるサブタイプであり、基底型が派生を許可する場合に限って、継承を選びます。sealed クラスや int などの値型から派生することはできません。また、継承によって基底クラスとの関係が生じますが、エイリアスにはそのような関係はありません。単に名前を短くするだけならエイリアスを使い、独自のドメイン概念を表す型が必要なら、その概念に必要な動作を考慮した派生型やラッパーを検討してください。

ラッパー型向けのサードパーティ製パッケージを評価する

サードパーティ製パッケージには、型をラップしたり別名を付けたりする補助機能が含まれている場合があります。ただし、それはパッケージの機能であり、組み込みの C# エイリアスではありません。追加する前に、ドキュメント、保守状況、互換性、ライセンス、API を確認してください。独立したラッパー型を作成するのか、どのような変換や操作に対応するのか、そうした仕様がコードに適しているかも調べます。

パッケージを追加すると、プロジェクトの利用者が復元や保守を行う必要のある依存関係が増えます。型名を短くするだけの目的でパッケージを追加するのは避けてください。型の識別性を変えずにその目的を果たすなら、using エイリアスで十分です。単純なエイリアスでは対応できない、より広い設計上のニーズを、確認済みの機能で満たせる場合にパッケージを検討します。