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