C#泛型:泛型类型推断失败意味着我无法使用匿名类型

问题描述

|| 我有一个Exporter类,该类具有一个通用方法,该方法接受ѭ0并通过使用反射枚举其属性值来创建导出文档:
  public class Exporter
  {
    public string Export<T>(IEnumerable<T> enumerable)
    {
      //Implementation omitted
    }
  }
由于通用类型推断,我可以为其提供匿名集合类型。请注意,下面的方法调用中没有通用参数:
string fooString =
        new Exporter().Export(new List<Foo>()
                                {
                                  new Foo() {Name = \"cats\",NumberOfHams = 1},new Foo() {Name = \"dogs\",NumberOfHams = 8}
                                }
                       .Select(x => new { TwiceTheHams = x.NumberOfHams * 2 }));
我们都喜欢C#3。但是,我想修改此类,以便可以输入有关导出文档中列的更多信息,例如宽度。 我在导出类中创建了一个新方法,如下所示:
public string Export<T>(IEnumerable<T> enumerable,IEnumerable<ColumnDetails<T>> columnDetails)
    {
      //Implementation omitted
    }
理想的语法是这样的,其中where4ѭ是of5ѭ类型:
fooString = new Exporter().Export(foos,new List<ColumnDetails<Foo>>
                                        {
                                          new ColumnDetails<Foo>(x => x.Name,12),new ColumnDetails<Foo>(x => x.NumberOfHams,4),});
但是,当我如上所述调用新的
Export()
重载时,泛型类型推断似乎不够聪明,无法推断出
ColumnDetails<T>
的泛型参数
T
应该与
IEnumerable
的泛型参数
T
相同。这意味着我必须指定“ 12”作为参数,因此我不能将其与匿名集合一起使用。 我真的是泛型和类型推断的新手。我想做的事可能吗?我需要以某种方式重组代码吗? 编辑:这是我不能做的,因为Visual Studio需要ColumnDetails的通用参数,而我没有:
fooString = new Exporter().Export(foos.Select(x => new {TwiceTheHams = x.NumberOfHams * 2}),new List<ColumnDetails>
                                            {
                                              new ColumnDetails(x => x.TwiceTheHams,12)
                                            });
    

解决方法

        这样的事情怎么样?
anonList
使您具有引用
IEnumerable<anontype>
,而
CreateColumnDetails<T>
中的
T foo
使编译器推断T是什么类型,从而允许您将匿名类型的对象构造为
T
的值。
class Program
{
    public static ColumnDetails<T> CreateColumnDetails<T>(T foo,Func<T,object> func,int x)
    {
        return new ColumnDetails<T>(func,x);
    }
    static void Main(string[] args)
    {
        IEnumerable<Foo> foos = new List<Foo>();
        var anonList = foos.Select(x => new {TwiceTheHams = x.NumberOfHams*2});
        var fooString = new Exporter().Export(anonList,anonList.Select(y => CreateColumnDetails(y,z => z.TwiceTheHams,12)));
    }
}
public class Exporter
{
    public string Export<T>(IEnumerable<T> enumerable,IEnumerable<ColumnDetails<T>> columnDetails)
    {
        return string.Empty;
    }
}

public class ColumnDetails<T>
{
    public ColumnDetails(Func<T,int x)
    {

    }
}
public class Foo
{
    public string Name { get; set; }
    public string NumberOfHams { get; set; }
}
    ,        这足以解决它吗? 导出
fooString = new Exporter().Export<Foo>(foos,new List<ColumnDetails<Foo>>
          {
               new ColumnDetails<Foo>(x => x.Name,12),new ColumnDetails<Foo>(x => x.NumberOfHams,4),});
    ,        因此,您想通过
List<ColumnDetails< *anonymouse type with TwiceTheHams property* >>
吗? 在我看来,您需要一个通用的辅助函数,该函数将使用
IEnumerable<T>
参数并从中构造construct23ѭ对象的列表。然后插入对该函数的调用,作为“ 24”的第二个参数。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...