雑記 - otherwise

最近はDQ10しかやっていないダメ技術者がちまちまと綴る雑記帳

nullable な引数を持つメソッドをオーバーロードする場合の解決・番外編

もう一個、このネタで引っ張ってみます。 :p
C# 3.0 で拡張メソッドを使った場合はどうなるか。

public static class FooExtension {
  public static void Hoge(this Foo foo, short? a) {
    Console.WriteLine("short");
  }
}

public class Foo {
  public void Hoge(int? a) {
    Console.WriteLine("int");
  }

  static void Main() {
    var foo = new Foo();
    foo.Hoge(null);          // (1)
    foo.Hoge((short?)null);  // (2)
  }
}

この場合、 (1) , (2) ともに「 int 」と出力されます。
これは、更続で書いた「『適切な関数メンバ』の検索」の対象に、拡張メソッドが含まれないためです。
※拡張メソッドは、適切なメソッドの検索で対象となるメソッドが見つからなかった場合に初めて検索対象となります。
なので当然の結果なのですが、知らないとはまるかもしれません。

おまけ

C#4.0 で名前付きプロパティを使ってみたら、ちゃんと拡張メソッドの方を呼んでくれました。

public static class FooExtension {
  public static void Hoge(this Foo foo, short? b) {
    Console.WriteLine("short");
  }
}

public class Foo {
  public void Hoge(int? a) {
    Console.WriteLine("int");
  }

  static void Main() {
    var foo = new Foo();
    foo.Hoge(null);          // (3)
    foo.Hoge((short?)null);  // (4)
    foo.Hoge(a:null);        // (5)
    foo.Hoge(b:null);        // (6)
  }
}

出力結果。

int    // (3)
int    // (4)
int    // (5)
short  // (6)

……これは、むしろ混乱の元かもしれないですね。 ^^;