'object' 基底クラス
CoddyのC#ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 23/70。
C#では、作成するすべてのクラスは、objectという特別なクラスを自動的に継承します。基本クラスを明示的に指定しない場合でも、クラスは依然としてobjectを究極の祖先として持ちます。これは、C#のすべての型が共通のメソッドセットを共有していることを意味します。
objectクラスは、自身のクラスでオーバーライドできるいくつかの仮想メソッドを提供します:
public class Person
{
public string Name { get; set; }
// object からのオーバーライド
public override string ToString()
{
return $"Person: {Name}";
}
public override bool Equals(object obj)
{
if (obj is Person other)
return Name == other.Name;
return false;
}
public override int GetHashCode()
{
return Name?.GetHashCode() ?? 0;
}
}最も一般的にオーバーライドされる3つのメソッドは、文字列表現のための ToString()、オブジェクトを比較するための Equals()、およびハッシュベースのコレクションのための GetHashCode() です。デフォルトでは、ToString() は型名を返し、Equals() は参照の等価性をチェックします。
すべてが object から継承されているため、任意の型を object 変数に格納できます:
object item1 = new Person { Name = "Alice" };
object item2 = 42;
object item3 = "Hello";
Console.WriteLine(item1.ToString()); // Person: Aliceこのユニバーサルな基底クラスこそが、異なる型が混在するコレクションのような機能を可能にしているものであり、C#のすべてのオブジェクトが ToString() や GetType() といったメソッドにアクセスできる理由でもあります。
チャレンジ
簡単object 基底クラスのメソッドをオーバーライドすることで、カスタム型に文字列表現や等価性チェックのための意味のある動作を与える方法を示す、本比較システムを構築しましょう。
コードを整理するために 2 つのファイルを作成します:
Book.cs:Library名前空間内にBookクラスを定義します。この本にはTitle(string) とAuthor(string) プロパティ、および両方の値を設定するコンストラクタが必要です。objectから継承された 3 つの主要なメソッドをオーバーライドしてください:ToString()は"{Title} by {Author}"を返す必要がありますEquals(object obj)は、もう一方のオブジェクトがBookであり、かつ同じTitleとAuthorを持っている場合にtrueを返す必要がありますGetHashCode()は、両方のプロパティのハッシュコードを組み合わせる必要があります
Program.cs: メインファイルで、入力値を使用して 2 つの本を作成します。ToString()を使用して各本を表示し、それらが等しいかどうかを確認して結果を出力します。最後に、Bookをobject変数に格納しても、ToString()を呼び出したときに意味のある出力が得られることを示します。
4 つの入力を受け取ります:
- 1 冊目の本のタイトル
- 1 冊目の本の著者
- 2 冊目の本のタイトル
- 2 冊目の本の著者
以下の形式で出力を表示してください:
Book 1: {ToString result}
Book 2: {ToString result}
Are they equal? {True/False}
Stored as object: {ToString result of first book stored in object variable}例えば、入力が 1984、George Orwell、1984、George Orwell の場合、出力は以下のようになります:
Book 1: 1984 by George Orwell
Book 2: 1984 by George Orwell
Are they equal? True
Stored as object: 1984 by George Orwell入力が 1984、George Orwell、Brave New World、Aldous Huxley の場合、出力は以下のようになります:
Book 1: 1984 by George Orwell
Book 2: Brave New World by Aldous Huxley
Are they equal? False
Stored as object: 1984 by George Orwellオーバーライドされたメソッドによって、Book オブジェクトに意味のある動作が与えられていることに注目してください。これらは文字列として適切に表示され、単なるメモリ参照ではなく、その内容によって比較できるようになります!
チートシート
C#では、すべてのクラスが自動的にobjectクラスを継承します。このクラスは、オーバーライド可能な複数の仮想メソッドを提供します。
オーバーライドされる一般的なObjectメソッド
ToString()- オブジェクトの文字列表現を返します(デフォルトでは型名を返します)Equals(object obj)- オブジェクトが等しいかどうかを比較します(デフォルトでは参照の等価性をチェックします)GetHashCode()- ハッシュベースのコレクションで使用するハッシュコードを返します
Objectメソッドのオーバーライド
public class Person
{
public string Name { get; set; }
// カスタムの文字列表現のためにToStringをオーバーライドする
public override string ToString()
{
return $"Person: {Name}";
}
// コンテンツベースの比較のためにEqualsをオーバーライドする
public override bool Equals(object obj)
{
if (obj is Person other)
return Name == other.Name;
return false;
}
// ハッシュベースのコレクションのためにGetHashCodeをオーバーライドする
public override int GetHashCode()
{
return Name?.GetHashCode() ?? 0;
}
}ユニバーサルな基底クラス
任意の型をobject型の変数に格納できます。
object item1 = new Person { Name = "Alice" };
object item2 = 42;
object item3 = "Hello";
Console.WriteLine(item1.ToString()); // Person: Aliceこのユニバーサルな継承により、混合型を保持するコレクションが可能になり、すべてのオブジェクトがToString()やGetType()などのメソッドにアクセスできることが保証されます。
自分で試してみよう
using System;
using Library;
class Program
{
public static void Main(string[] args)
{
// 2冊の本の入力を読み込む
string title1 = Console.ReadLine();
string author1 = Console.ReadLine();
string title2 = Console.ReadLine();
string author2 = Console.ReadLine();
// TODO: 入力値を使用して2つの Book オブジェクトを作成する
// TODO: ToString() を使用して Book 1 を表示する
// 形式: "Book 1: {ToString result}"
// TODO: ToString() を使用して Book 2 を表示する
// 形式: "Book 2: {ToString result}"
// TODO: 本が等しいかどうかを確認し、結果を表示する
// 形式: "Are they equal? {True/False}"
// TODO: 1冊目の本を object 変数に格納して表示する
// 形式: "Stored as object: {ToString result}"
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。