名前空間(namespace)を理解しよう!

[C#] 名前空間(namespace)を理解しよう!

※ 当サイトは広告を含みます。

ここではC#の名前空間について学びます。

名前空間 (namespace)

名前空間とは、複数のクラス等を1つの領域にまとめる機能です。
この仕組みを使うことで、ある程度の機能を1つのスコープにまとめることができます。

名前空間を定義する方法

まとめたい領域をnamespace{}で囲みます。
実は最初から何度も登場してますが、改めて確認しましょう。

では、以下が構文とサンプルコードです。

名前空間

// 名前空間のOSを定義
namespace OS
{
  public class Windows
  {
    public string Text()
    {
      return "Windows";
    }
  }

  public class MacOS
  {
    public string Text()
    {
      return "MacOS";
    }
  }
}

// 名前空間のCompanyを定義
namespace Company
{
  public class Microsoft
  {
    public string Text()
    {
      return "Microsoft";
    }
  }

  public class Apple
  {
    public string Text()
    {
      return "Apple";
    }
  }
}

// 名前空間のSampleを定義
namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      var windows = new OS.Windows();
      var macos = new OS.MacOS();

      var microsoft = new Company.Microsoft();
      var apple = new Company.Apple();

      System.Console.WriteLine(windows.Text());
      System.Console.WriteLine(macos.Text());
      System.Console.WriteLine(microsoft.Text());
      System.Console.WriteLine(apple.Text());
    }
  }
}

名前空間としてOS, Company, Sampleを作りました。そして、配下にクラスが存在します。

この様に名前空間を分けることで、関連する機能を1つの空間に整理できます。
ちなみにstatic void Mainは大抵がプロジェクト名と同じ名前空間に存在します。

なお、今回は学習のために1つのファイルに記述してますが、通常は1つのファイルに1つの名前空間しか書きません。
加えて1つのファイルに複数のクラスを記述することも少ないため、実際には複数のファイルから構成されます。

その場合は次のようにファイルを分割します。この時に同じ名前空間を記述すれば、それは同じ領域に収まります。

◆ Windows.cs


namespace OS
{
  public class Windows
  {
    public string Text()
    {
      return "Windows";
    }
  }
}

◆ MacOS.cs


namespace OS
{
  public class MacOS
  {
    public string Text()
    {
      return "MacOS";
    }
  }
}
Tips普通は1つのファイルに1つの名前空間しか書かない。

ファイル全体を名前空間の対象にする方法

1つのファイルに1つの名前空間しか記述しない場合、ファイルの先頭に;(セミコロン)付きの名前空間を記述することで、{}で囲まない記述もできます。


namespace Sample; // ;で記述すると{}不要

public class Windows
{
  public string Text()
  {
    return "Windows";
  }
}

internal class Program
{
  static void Main(string[] args)
  {
    var windows = new Sample.Windows();
    System.Console.WriteLine(windows.Text());
  }
}
管理人

見ての通りインデントが1ランク減ります。

名前空間を利用する方法

名前空間を利用するには.(ドット演算子)を使用して、名前空間とクラスを繋ぎます。
これはディレクトリ(=namespace)ファイル(=class)の関係に非常に似てます。

実際にC#では名前空間を利用してクラスを作ると、その名前空間がディレクトリとして作成されます。
もちろん定義名は自由に変更できるため、実ディレクトリと名前空間が異なることもありますが、殆どの場合で同じです。


var windows = new OS.Windows(); // .演算子で繋ぐ
System.Console.WriteLine(windows.Text());

名前空間の階層化

名前空間を.演算子で繋ぐか、名前空間の下に名前空間を記述すると階層構造になります。
考え方はディレクトリ構造と同じで、似た機能を持つ名前空間を階層化してまとめます。


// 名前空間のOSを定義
namespace OS
{
  // 名前空間のAmericaを定義
  namespace America
  {
    public class Windows
    {
      public string Text()
      {
        return "Windows";
      }
    }

    public class MacOS
    {
      public string Text()
      {
        return "MacOS";
      }
    }
  }
}

// 名前空間のCompany.Americaを定義
namespace Company.America
{
  public class Microsoft
  {
    public string Text()
    {
      return "Microsoft";
    }
  }

  public class Apple
  {
    public string Text()
    {
      return "Apple";
    }
  }
}

namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      var windows = new OS.America.Windows();
      var macos = new OS.America.MacOS();

      var microsoft = new Company.America.Microsoft();
      var apple = new Company.America.Apple();

      System.Console.WriteLine(windows.Text());
      System.Console.WriteLine(macos.Text());
      System.Console.WriteLine(microsoft.Text());
      System.Console.WriteLine(apple.Text());
    }
  }
}

名前空間のスコープ

名前空間が異なる場合、それは完全に別の領域になります。これは変数と同じですね。
つまり、異なる名前空間の下に同名のクラスを定義した場合、それは別々のクラスとして扱われます。


namespace OS1
{
  public class Windows
  {
    public string Text()
    {
      return "OS1.Windows";
    }
  }
}

namespace OS2
{
  public class Windows
  {
    public string Text()
    {
      return "OS2.Windows";
    }
  }
}

namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      var windows1 = new OS1.Windows();
      var windows2 = new OS2.Windows();

      System.Console.WriteLine(windows1.Text());
      System.Console.WriteLine(windows2.Text());
    }
  }
}

usingディレクティブ

名前空間が長くなると利用する場合に記述するのが大変ですよね。
そんな時に便利なのがusingです。まずはサンプルコードを確認しましょう。


using OS.America; // using宣言

namespace OS
{
  namespace America
  {
    public class Windows
    {
      public string Text()
      {
        return "Windows";
      }
    }

    public class MacOS
    {
      public string Text()
      {
        return "MacOS";
      }
    }
  }
}

namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      var windows = new Windows(); // 記述を省略できる
      var macos = new MacOS();     //   〃

      System.Console.WriteLine(windows.Text());
      System.Console.WriteLine(macos.Text());
    }
  }
}

こんな感じに予め利用する名前空間を宣言することで、ファイル内に限り、それより先のコードでは名前空間の記述が不要になります。
普通ならusingはソースコードの先頭にしか記述しませんが、実際には途中にも記述できます。ただし、クラス内みたいな場所は駄目です。

ちなみにC#の基本となるSystem名前空間は勝手にusingされてます。それもあってSystem.Console.WriteLineは省略しても動きますよ。
実はこれ、昔は自分でusing System;って書いてたのですが、いつの間にか不要になりました。たぶん、.NETくらいからです(適当)。

管理人

IDEが進化して長い名前空間も簡単に入力できるから、無理に省略することに価値ないと思う。

POINT標準的に利用される名前空間は自動的にusingされる。

using エイリアス ディレクティブ

どこで使われてるのか知りませんが、usingに別名を付けることができます。
個人的に覚える必要ないと思ってるので、サンプルコードだけ紹介しておきます。


using My = OS.America; // 別名を付ける

namespace OS
{
  namespace America
  {
    public class Windows
    {
      public string Text()
      {
        return "Windows";
      }
    }

    public class MacOS
    {
      public string Text()
      {
        return "MacOS";
      }
    }
  }
}

namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      var windows = new My.Windows(); // 別名で参照する
      var macos = new My.MacOS();     //   〃

      System.Console.WriteLine(windows.Text());
      System.Console.WriteLine(macos.Text());
    }
  }
}
管理人

これマジでメリットないと思うんだよね。普通に1つ上の階層をusingすれば良くね?

りさ

別名を付けてる分、より所属する場所が分かりづらくなった印象です。

.NETの名前空間

業務なら真面目に名前空間の設計をしないと悲しいことになりますが、小規模なプログラムは1つの名前空間でも問題になりません。
どちらかと言うと名前空間の設計よりも利用する知識のほうが大切で、実際には.NETに定義されてる膨大なLibraryを利用するために使います。

POINTLibraryとは、ある機能を他のプログラムから呼び出せるようにした仕組みです。
.NETのように名前空間で参照すれば使える場合もあれば、外部から取り込む場合もあります。

このLibraryを利用することで、大半の機能は自前で作ることもなく、プログラム全体を開発できます。
例えば、以下はCドライブ直下のディレクトリを取得するサンプルコードです。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      foreach (var file in System.IO.Directory.GetDirectories(@"C:\"))
        System.Console.WriteLine(file);
    }
  }
}
管理人

この例ではSystem.IO.Directoryに属するGetDirectories()を呼び出しました。名前通りの機能ですね。

りさ

名前空間もメソッド名も分かりやすいです。

管理人

そうです。.NETは一流のエンジニアが設計してるので名前空間の定義が素敵です。自分で作る時は是非参考にしましょう。

あとがき

プログラミングを続けてれば設計は勝手に身につくので、機能を利用する知識のほうが大切です。
.NETを使う限りは自分で作るより、まずは既存の実装があるかどうかを調べたほうがいいです。

◆ C#に関する学習コンテンツ

この記事は参考になりましたか?

関連記事

コメント

この記事へのコメントはありません。