[C#] 34. 最上位クラス(Object クラス)


Study / C#    作成日付 : 2019/07/20 02:27:23   修正日付 : 2021/09/21 19:47:40

こんにちは。明月です。


この投稿は最上位クラス(Object クラス)に関する説明です。


C#にはオブジェクトの最小単位がクラスになっています。

link - [C#] 10. クラスを作成する方法(コンストラクタ、デストラクタ)


そのクラスは基本的にObjectのクラスを継承することになっています。

link - [C#] 13. クラスの継承と再定義(override)する方法、overrideとnewの差異


その意味はクラスの隣に継承する定義をしなくてもObjectクラスを継承します。つまり、C#に存在するすべてのクラスはObjectクラスを継承します。

Objectクラスの基本構成は下記通りです。


基本的にStaticが付けてないEquals関数は比較(クラスの中でメンバー変数のデータではなく、インスタンスが同じかを比較)関数、GetHashCode関数はポインタアドレスをHashデータで変換した値、GetTypeはクラスのデータタイプ、ToStringはクラスをStringタイプに表す関数、MemberwiseCloneの関数はデザインパターンのプロトタイプのクラスインスタンスコピー(ポインタコピーではなく、クラスのデータがすべて複製)があります。

つまり、すべてのクラスは上の関数を基本的に継承して使えます。

using System;

namespace Example
{
  class Program
  {
    // メンバー変数のプロパティ
    public int Data
    {
      get; set;
    }
    // 実行関数
    static void Main(string[] args)
    {
      // インスタンス生成
      var p1 = new Program();
      p1.Data = 100;
      var p2 = new Program();

      // p1とp2のインスタンスが同じか確認
      Console.WriteLine("p1 == p2 -> " + p1.Equals(p2));
      // ポインタアドレスをHashCodeでリターン
      Console.WriteLine("p1.GetHashCode() -> " + p1.GetHashCode());
      // クラスタイプ
      Console.WriteLine("p1.GetType() -> " + p1.GetType());
      // ToStringの結果
      Console.WriteLine("p1.ToString() -> " + p1.ToString());

      // インスタンスコピー
      var p3 = p1.MemberwiseClone() as Program;
      // p1とp3のインスタンスが同じか確認
      // インスタンスを個ぴ^したが別のインスタンスなのでfalse
      Console.WriteLine("p3 == p2 -> " + p3.Equals(p2));
      Console.WriteLine("p3.GetHashCode() -> " + p3.GetHashCode());
      Console.WriteLine("p3.Data -> " + p3.Data);

      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadLine();
    }
  }
}


上の例をみればProgramクラスはObjectクラスを明示的に継承してないです。でも、Objectの関数を使えますね。

つまり、明示的に継承することを実装しなくても、クラスは基本的にObjectクラスを継承することを確認できます。


そしてEquals関数とGetHashCode関数、ToString関数はvirtualキーワードが付けているので再定義も可能です。

using System;

namespace Example
{
  // クラス
  class Program
  {
    // ToString関数の再定義
    public override string ToString()
    {
      // string文字リターン
      return "Hello world";
    }
    // Equals関数再定義
    public override bool Equals(Object obj)
    {
      // nullならfalse
      if (obj == null)
      {
        return false;
      }
      // データタイプが違いならfalse
      if (obj.GetType() != typeof(Program))
      {
        return false;
      }
      // インスタンスポインタアドレスが同じならtrue、違いならfalse
      return this.GetHashCode() == obj.GetHashCode();
    }
    // GetHashCode関数再定義
    public override int GetHashCode()
    {
      // インスタンスポインタはhashcodeではなく、他の値でリターンが可能
      // 参考にStringクラスはりてリテラルの値
      return base.GetHashCode();
    }
    // 実行関数
    static void Main(string[] args)
    {
      // インスタンス生成
      var p1 = new Program();
      var p2 = new Program();

      // p1とp2のインスタンスが同じか確認
      Console.WriteLine("p1 == p2 -> " + p1.Equals(p2));
      // ポインタアドレスをHashCodeでリターン
      Console.WriteLine("p1.GetHashCode() -> " + p1.GetHashCode());
      // クラスタイプ
      Console.WriteLine("p1.GetType() -> " + p1.GetType());
      // ToStringの結果
      Console.WriteLine("p1.ToString() -> " + p1.ToString());

      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadLine();
    }
  }
}


上の例ををみればEquals関数とGetHashCode関数、ToString関数を再定義します。

なのでGetHashCodeの関数は常にインスタンスポインタアドレスではない可能性もあります。参考にStringクラスのGetHashCodeはポインタアドレスではなく、リテラル値です。

Stringに関しては他の投稿で詳細に説明します。


Objectのクラスは最上位クラスになるので、変数宣言する時、どのインスタンスでも変数のデータタイプに設定することができます。

using System;

namespace Example
{
  class Program
  {
    // 関数作成
    public void Print()
    {
      // コンソール出力
      Console.WriteLine("Hello world");
    }
    // 実行関数
    static void Main(string[] args)
    {
      // インスタンス生成
      object p1 = new Program();
      // ProgramクラスにはPrint関数があるが、objectクラスの関数ではないので、エラーが発生
      p1.Print();

      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadLine();
    }
  }
}


objectクラスにはPrintという関数がないので、エラーが発生します。

dynamicキーワードが基本的にobjectのデータタイプですが、該当なデータタイプに関数や変数が存在しなくてもReflection機能で関数や変数を探すのでエラーが発生しません。

objectデータタイプはデバッグ段階でエラーが発生します。


ここまで最上位クラス(Object クラス)に関する説明でした。


ご不明なところや間違いところがあればコメントしてください。

#C#
最新投稿