void PrintInfo(Person)
となどのようにオーバーロードされているメソッドがあるvoid PrintInfo(Item)
とします。オブジェクトを渡してこれらのメソッドを呼び出そうとします。
これを行うと、なぜエラーが発生するのか疑問に思います。すべてのクラスがObjectから継承されていませんか?適切なメソッドを呼び出す前に、オブジェクトのタイプを確認するif/switchステートメントを実行しないようにします。
この場合の最善のアプローチは何だと思いますか?
void PrintInfo(Person)
となどのようにオーバーロードされているメソッドがあるvoid PrintInfo(Item)
とします。オブジェクトを渡してこれらのメソッドを呼び出そうとします。
これを行うと、なぜエラーが発生するのか疑問に思います。すべてのクラスがObjectから継承されていませんか?適切なメソッドを呼び出す前に、オブジェクトのタイプを確認するif/switchステートメントを実行しないようにします。
この場合の最善のアプローチは何だと思いますか?
すべてPerson
の s はs ですが、すべてのsがobject
s であるとは限りません。このため、を受け入れるメソッドに を渡すことはできますが、 を必要とするメソッドに を渡すことはできません。object
Person
Person
object
object
Person
使用したいさまざまなオブジェクト間で共通の機能がいくつかあるようです。これを考えると、必要なすべての機能を備えた共通の祖先、またはすべてが実装するインターフェイス (必要なものすべてを提供する) のいずれかを見つけるのが最善です。
印刷の場合は、ToString
メソッドだけが必要な場合があります。その場合、メソッドに を受け入れさせ、object
それを呼び出すことができToString
ます。(これは、 などの多くの印刷メソッドが行うことですConsole.WriteLine
。
dynamic
C# は静的に型付けされた言語 (禁止) であるため、選択された特定のオーバーロード (オーバーロードの解決と呼ばれます) は、実行時ではなくコンパイル時に決定されることを理解する必要があります。つまり、コンパイラは、引数の型を明確に判断できる必要があります。検討:
Object foo;
foo = "String";
foo = 5;
PrintInfo(foo); // Which overload of printinfo should be called? The compiler doesn't know!
これを解決する方法はいくつかありますfoo
。型の作成はdynamic
、コンパイル時に正しいオーバーロードが選択されるようにする方法の 1 つです。その問題は、型の安全性が失われることです。その型に適切なオーバーロードがない場合でも、アプリケーションはコンパイルされますが、サポートされていない型の情報を出力しようとするとクラッシュします。
間違いなくより良いアプローチはfoo
、単にObject
.
@Servy が示唆するように、別のアプローチは、動作を型自体にアタッチすることです。たとえば、インターフェイスを作成できますIHasPrintInfo
。
public interface IHasPrintInfo { String PrintInfo { get; } }
情報を印刷する可能性のあるすべてのアイテムにそのインターフェイスを実装します。次に、PrintInfo 関数は IPrintInfo を取得できます。
public void PrintInfo(IPrintInfo info) {
Console.WriteLine(info.PrintInfo);
}
ここでは、コンパイラのあいまいさです。コンパイラは、呼び出す予定のメソッド (Person/Item) のバージョンを特定できません。