はじめに:完全な説明が必要な場合は、編集をスキップしてください。 Spoiler:拡張メソッドはコンパイラのトリックであり、実際に呼び出すときのように1つ以上の引数を持っています。。
これはメソッドグループの解決です。どうやらC#コンパイラは、使用しているメソッドが過負荷かどうかを判断する時間がかかりません。それは常に明示的なキャストが必要です。チェックアウト:
What is a method group in C#?
Method Inference does not work with method group
あなたはそれをキャストしようとするもので絞られるバックreader.GetDoubleOrNull
からくる方法グループ:GetDoubleOrNull
は、その名前のオーバーロードされた任意の数の方法を参照することができます。明示的にキャストする必要があります。
興味深いことに、あなたも同じ理由で暗黙的に型指定された変数にメソッドグループを割り当てることができません。
var x = reader.GetDoubleOrNull;
は、それが明示的なキャストが必要なため、コンパイルに失敗しました。
編集私はここで混乱が拡張メソッドに関係していることをかなり確信している:
は、次のテストクラスをチェックアウト:
public static class Extensions
{
public static List<T> GetList<T>(this IDataReader reader, Func<string, T> del)
{
throw new NotImplementedException();
}
public static double? GetDoubleOrNull(this IDataReader reader, string columnName)
{
throw new NotImplementedException();
}
public static double? blah(this string s)
{
throw new NotImplementedException();
}
}
をあなたは成功し
var x = reader.GetList(Extensions.blah);
を呼び出すことができます
なぜこれがである可能性がありますか? blah
も静的な拡張メソッドなので、あなたの証拠に基づいて、上記の行はコンパイルしないように見えます。さらに物事を複雑、のは、このメソッドを追加してみましょう。
public static List<T> GetList2<T>(this IDataReader reader, Func<IDataReader, string, T> del)
{
throw new NotImplementedException();
}
あなたは今
x = reader.GetList2(Extensions.GetDoubleOrNull);
を呼び出すことができ、それが適切にコンパイルします。何がありますか?
ここに答えがあります:拡張メソッドはありません実際にはオブジェクトにメソッドを追加します。実際には、それらのメソッドがクラスの一部であるかのようにプログラムすることができます。 hereから:あなたのコードで
あなたはインスタンスメソッド 構文で拡張メソッドを呼び出します。ただし、コンパイラ によって生成された中間言語(IL)は、コードを静的メソッドの呼び出しに変換します。 したがって、カプセル化の原則は実際には に違反していません。実際に、拡張メソッドは拡張型のプライベート変数 にはアクセスできません。だから、
var x = Extensions.GetDoubleOrNull(reader, "myColumnName");
:あなたは(それは拡張メソッドだにも関わらず、完全に合法的な呼び出し)、実際にコンパイルして実行されているもの
var x = reader.GetDoubleOrNull("myColumnName");
は、本質的にこれです呼び出すので
、 GetDoubleOrNull
をFunc<string, double?>
の引数として使用しようとすると、コンパイラは「GetDoubleOrNull
をFunc<IDataReader, string, double?>
にすることができますが、これには2つの引数がありますが、kはしません今では1つの引数とIDataReader
のインスタンスメソッドだかのようにあなたがそれを呼んでいるにもかかわらずFunc<string, double?>
「
にそれを有効にする方法、それはではない:それはだ2つの引数のC#での静的なメソッドコンパイラはあなたを思考に誘惑して、IDataReader
の一部です。
非常に興味深い。明示的キャスト '' var x = reader.GetList((Func)リーダです。GetDoubleOrNull) ''も動作します。 Resharperはキャストを冗長としてマークしますが、コンパイルが失敗すると失敗します。 Jon Skeetはまわりですか? –
Jon Skeet(またはEric Lippert)を呼び出す方法はありますか?彼らの名前を3回か何か言ってください? – Chris
関連:http://stackoverflow.com/questions/7745852/method-inference-does-not-work-with-method-groupおよびhttp://stackoverflow.com/questions/2057146/compiler-ambiguous-invocation-error -anonymous-method-and-method-group-with-fun – AakashM