【发布时间】:2011-05-27 21:14:02
【问题描述】:
我有一个类 Exporter,它有一个通用方法,它接受 IEnumerable<T> 并通过使用反射枚举其属性值来创建导出文档:
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
}
理想情况下,语法应该是这样的,其中foos 的类型是IEnumerable<Foo>:
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。这意味着我必须将List<ColumnDetails<Foo>> 指定为参数,因此我不能将它与匿名集合一起使用。
我对泛型和类型推断非常陌生。我正在尝试做的事情可能吗?我需要以某种方式重组代码吗?
编辑:这是我不能做的,因为 Visual Studio 需要 ColumnDetails 的通用参数,而我没有:
fooString = new Exporter().Export(foos.Select(x => new {TwiceTheHams = x.NumberOfHams * 2}),
new List<ColumnDetails>
{
new ColumnDetails(x => x.TwiceTheHams, 12)
});
【问题讨论】:
-
我在提供的代码中看不到任何泛型的原因。
-
当您谈论“匿名集合”和“匿名类型”时,我认为您真的不是指匿名类型 - 至少,您没有显示任何调用
Export使用匿名类型。如果你能给出一个失败的完整例子,那真的很有帮助...... -
@Tomas:这意味着您可以提供任何对象(例如业务实体)的 IEnumerable 并将其导出为一种报告。或 Linq 查询的输出。如果没有泛型,我看不到这样做的方法。
-
@Jon:第二个代码块使用匿名类型的集合调用 Export
方法(我的意思是匿名集合)。提供给它的 IEnumerable 使用 Select() 方法投影到匿名类型。 -
@David:啊,我将 Select 的调用误读为 导出之后。只显示匿名类型值的普通集合会更简单,例如
new[] { new { X="x" }, new { X="y" }。同样,一个完整的例子会很有用。 (例如,当T是匿名的时,你是如何创建List<ColumnDetails<T>>的?)
标签: generics c#-3.0 type-inference