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参数 (via 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 回答