Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 继承过程中的表达式推理_C#_Compiler Errors_Expression Trees_Type Inference - Fatal编程技术网

C# 继承过程中的表达式推理

C# 继承过程中的表达式推理,c#,compiler-errors,expression-trees,type-inference,C#,Compiler Errors,Expression Trees,Type Inference,我有以下代码: 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 Figur

我有以下代码:

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; }
}
然后它就起作用了。有没有办法通过更改基类来获得要编译的第一个示例

我知道如果我让整个基类都是泛型的,就像这样:

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; }
}

然后它就可以工作了,但我不想这样做,可能在方法层面上,也就是说,以某种方式进行更改。

调用实际受保护的内部实现的扩展方法怎么样?唯一的缺点是你必须加上这个

这是因为源参数通过它推断TClass的类型


调用实际受保护的内部实现的扩展方法如何?唯一的缺点是你必须加上这个

这是因为源参数通过它推断TClass的类型


除非采用参数,否则无法推断。
除非它指定一个返回值,否则无法对其进行推断。

除非它接受一个参数,否则无法对其进行推断。
除非它指定一个返回值,否则它不能被推断。

不要忘记arg0 aka这也是一个可以驱动类型推断的参数,特别是通过扩展方法。不要忘记arg0 aka这也是一个可以驱动类型推断的参数,特别是通过扩展方法。嗯,这解决了另一个问题,与一些钻石形状的继承问题有关,但它也暴露了外人的图解方法,我们必须考虑这是否是我们可以共存的权衡。请注意,您也可以将BaseExt设置为内部…问题是,我在问题中没有说明这一点,但基类在类库中,而子类在另一个类库中,或者在应用程序项目中,所以仍然存在一些问题here@lassevk-在这种情况下,只考虑一个基础上受保护的静态方法,它接受一个实例作为第一个参数,并使用FigureItOutthis,C= > C.No--几乎一样好。HMM,这解决了另一个问题,涉及到一些菱形继承问题,但是它也将图形化方法暴露给局外人,我们必须考虑,如果这是一个我们可以共存的权衡。请注意,您也可以将BaseExt设置为内部…问题是,我在问题中没有说明这一点,但基类在类库中,而子类在另一个类库中,或者在应用程序项目中,所以仍然存在一些问题here@lassevk-在这种情况下,只考虑一个基础上受保护的静态方法,它接受一个实例作为第一个参数,使用FigureItOutthis,c= > c-名称几乎一样好。我添加了一个避免内部需求的替代方案,并且扩展方法增加了一个避免内部需求和扩展方法的替代方案。
FigureItOut((Descendant c) => c.Name);
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; }
}
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; }
}
protected static void FigureItOut<TClass, TMember>(TClass source, Expression<Func<TClass, TMember>> expr)
{

}

public void TestMethod()
{
    FigureItOut(this, c => c.Name);
}