1

次のコードがあります。

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 を何らかの方法で変更する)ではなく、それを行いたくありません。

4

2 に答える 2

6

protected internal実際の ( ) 実装を呼び出す拡張メソッドはどうですか? 唯一の欠点は、追加する必要があること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);
}
于 2008-11-04T12:36:33.800 に答える
0

パラメータを取らない限り、推論できません。戻り値を割り当てない限り、推測できません。

于 2008-11-04T12:37:02.643 に答える