24 親クラスやインターフェイス用に特化したジェネリックメソッドを作成しないこと
オーバーロード解決について。 ジェネリックメソッドは、型パラメータをそれぞれに該当するあらゆる型と一致できる。暗黙的型変換(例えば親クラスへの変換)よりも優先されるため、使用する側にとってわかりにくくなる場合がある。使用する側が混乱しないように実装すべき。
オーバーロード解決のルール
一致度が高いものが優先される
引数の型
引数の型は、以下のリストの上の方ほど「一致度が高い」と判断されます。
例
public class MyBase{} public interface IMessageWrite{/*略*/} public class MyDerived : MyBase, IMessageWrite{/*略*/} public class AnotherType : IMessageWriter{/*略*/} static void WriteMessage(MyBase b){/*略*/} static void WriteMessage<T>(T obj){/*略*/} static void WriteMessage(IMessageWriter obj){/*略*/} MyDerived d = new MyDerived(); WriteMessage(d); //WriteMessage<T>(T) MyDerived WriteMessage((IMessageWriter)d); //IMessageWriter MyDerived WriteMessage((MyBase)d); //WriteMessage(MyBase) MyDerived AnotherType anObject = new AnotherType(); WriteMessage(abObject); //WriteMessage<T>(T) AnotherType WriteMessage((IMessageWriter)anObject); //IMessageWriter AnotherType
MyDerived
に厳密に一致するのはジェネリックメソッド。
親クラスであるMyBase
には暗黙的型変換が必要なため優先度が下がる。
明示的な変換を行えば変換後のものが厳密に一致となる。
※static void WriteMessage<T>(T obj)
をコメントアウトすると WriteMessage(d);
でエラーになる
次のメソッドまたはプロパティ間で呼び出しが不適切です: 'Program.WriteMessage(MyBase)' と'Program.WriteMessage(IMessageWriter)'
親クラスの方が優先順位高いはずだけど…わからん。