編集
残念ながら、デフォルトのメソッドを定義するように依頼した場所を見逃していました。これは不可能です。C# では、コンパイル時定数ではないものに対して既定のパラメーターを割り当てることを明示的に禁止しています。これを回避する唯一の方法は、オーバーロードされたメソッドをいくつかセットアップすることです。
public static T Read<T>(T input)
{
Read(input, ExtensionMethods.ConversionA<T>);
}
public static T Read<T>(T input, Func<T, string> conversion)
{
// Logic goes here
}
全体として、それほど悪くはありません。これはほんの少しの余分なコードであり、探している動作が得られます。
オリジナル
あなたが持っているものは本質的に機能するはずです。を受け入れることを指定するだけですFunc<T, string>
。常にConversionA<T>
またはのいずれかになることを強制することはできませんConversionB<T>
が、これらの型シグネチャのいずれかが を満たす必要がありFunc<T, string>
ます。
例(変換メソッドが何をするかわからないので、自分で作成します):
public static class Conversions
{
public static string UpperString<T>(T self)
{
return self.ToString().ToUpper();
}
public static string LowerString<T>(T self)
{
return self.ToString().ToLower();
}
}
public static T Read<T>(T input, Func<T, string> conversion)
{
// Do-whatchya-do
}
void Main()
{
Read<SomeObj>(new SomeObj(), Conversions.UpperString<SomeObj>);
Read<SomeObj>(new SomeObj(), Conversions.LowerString<SomeObj>);
}
最終的に「Read」を呼び出すときに、ジェネリック メソッドを正しい型で渡すだけで済みます。そのため、型シグネチャを少し複製する必要があるかもしれませんが、問題なく動作するはずです。
それらが拡張メソッドであることは何も変わりません。任意の拡張メソッドを非拡張形式で明示的に使用できます。例えば:
public static class Extensions
{
public static T SomeExtension<T>(this T value) { /* ... */ }
}
次の両方の方法で呼び出すことができます。
someT.SomeExtension();
Extensions.SomeExtension(someT);