-
06-07-2019 - |
質問
次のコードがあります:
using System;
using System.Linq;
using System.Linq.Expressions;
public class Program
{
public static void Main()
{
Descendant d = new Descendant();
d.TestMethod();
}
}
public class Base
{
protected void FigureItOut<TClass, TMember>(Expression<Func<TClass, TMember>> expr)
{
}
}
public class Descendant : Base
{
public void TestMethod()
{
FigureItOut(c => c.Name);
}
public String Name { get; set; }
}
このコンパイラエラーメッセージが表示されます:
The type arguments for method
'Base.FigureItOut<TClass,TMember>
(System.Linq.Expressions.Expression<System.Func<TClass,TMember>>)'
cannot be inferred from the usage. Try specifying the type arguments explicitly.
FigureItOutへの呼び出しをこれに変更した場合:
FigureItOut((Descendant c) => c.Name);
それで動作します。代わりに基本クラスを変更してコンパイルする最初の例を取得する方法はありますか?
次のようにBaseクラス全体をジェネリックにすると、次のようになります。
public class Base<TDescendant>
{
protected void FigureItOut<TMember>(Expression<Func<TDescendant, TMember>> expr)
{
}
}
public class Descendant : Base<Descendant>
{
public void TestMethod()
{
FigureItOut(c => c.Name);
}
public String Name { get; set; }
}
その後は動作しますが、メソッドレベルで使用できる他のハッキング(つまり、何らかの方法でFigureItOutを変更する)は実行しません。
解決
実際の(保護された内部
)実装を呼び出す拡張メソッドはどうですか?唯一の欠点は、 this。
を追加する必要があることです。
これは、 source
パラメーター( this
を使用)が TClass
の型を推測するために機能します。
public class Base
{
protected internal void FigureItOut<TClass, TMember>(Expression<Func<TClass, TMember>> expr)
{
Debug.WriteLine("Got to actual method");
}
}
public static class BaseExt
{
public static void FigureItOut<TClass, TMember>(this TClass source, Expression<Func<TClass, TMember>> expr)
where TClass : Base
{ // call the actual method
Debug.WriteLine("Got to extension method");
source.FigureItOut(expr);
}
}
public class Descendant : Base
{
public void TestMethod()
{
this.FigureItOut(c => c.Name);
}
public String Name { get; set; }
}
代替として( internal
が苦痛の場合)、主に型推論に使用されるインスタンス引数を使用して、静的にすることを検討してください:
protected static void FigureItOut<TClass, TMember>(TClass source, Expression<Func<TClass, TMember>> expr)
{
}
public void TestMethod()
{
FigureItOut(this, c => c.Name);
}
他のヒント
パラメータを受け取らない限り、推測することはできません。 戻り値を割り当てない限り、推測することはできません。
所属していません StackOverflow