c# - 我可以使用 linq 结果中的匿名类型来创建类集合作为方法参数的一部分吗?

标签 c# linq

我正在从源中选择一些数据,并且希望将其传递给处理数据的通用方法。我选择的每个属性都需要一些关联的元数据来进行处理。这大致就是我希望能够做到的:

var items = from i in db.bar
            select new {
                a = i.Prop1.ToString(),
                b = i.Prop2.ToString(),
                c = Prop3
            };

// Roughly what I would like to be able to do:
ProcessData(items,
    new DataSelector() { Header = "head1", Selector = (d => d.Prop1) },
    new DataSelector() { Header = "head2", Selector = (d => d.Prop2) });

我能得到的最接近的是:

private class DataSelector<T> {
    public string Header { get; set; }
    public Func<T, string> Selector { get; set; }
}

private static void Process<T>(IEnumerable<T> stuff,
                               params ColumnDef<T>[] defs) {
    foreach (var item in stuff) {
         // Use all defs like...
         Console.WriteLine(defs[0].Header + ": " + defs[0].Selector(item));
    }
}

Process(items,
    new DataSelector<dynamic>() { Header = "head1", Selector = (d => d.Prop1) });

但这允许我写(d => d.NonExistantProp)它会编译并在运行时失败(嘘声)。我还可以对单个属性执行此操作并维护类型安全,因为该类型似乎是隐式计算出来的,但这不会让我传递参数集:

private static void Process<T>(IEnumerable<T> stuff,
                               string header,
                               Func<T, string> selector) {
     // stuff happens
}

Process(items, "head1", (d => d.Prop1));

那么...有没有办法维护选择器以及相关数据组的编译时类型安全?

脚注:我很感激我可以拥有 Process<T>(IEnumerable<T> items, List<string> headers, params Func<T, string> selectors[])但如果 header 未与选择器配对,也会产生运行时错误。

最佳答案

您需要的是创建一个 DataSelector 的方法,该方法使用基于给定序列(或项目,或使用该类型的任何其他内容)的类型推断。

我们可以创建一个非通用的 DataSelector 对应项,它可以有一个静态 Create 方法,该方法可以以允许类型推断的方式编写:

private class DataSelector
{
    public static DataSelector<T> Create<T>(IEnumerable<T> sequence,
        string header, Func<T, string> selector)
    {
        return new DataSelector<T>() { Header = header, Selector = selector };
    }
}

现在调用者可以写:

Process(items, DataSelector.Create(items, "first", item => item.Prop1));

我们现在正在推断数据选择器的 T 类型,并且不需要指定没有名称的类型。

请注意,我们实际上并没有在此 Create 方法中迭代序列;它根本没有被使用;它基本上是一个虚拟参数。

我们看到这种模式在 .NET 框架的许多地方都有使用,例如 Tuple

关于c# - 我可以使用 linq 结果中的匿名类型来创建类集合作为方法参数的一部分吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20078491/

相关文章:

c# - 对象图的元数据模式

c# - 将 lambda 表达式转换为用于缓存的唯一键

c# - 在 linq 中使用 GroupBy 对字符串的字母进行分组

c# - 使用 XPath 测试当前节点

c# - Web.config 中的程序集

c# - asp.net LinqDataSource 使用 join 查询多个表

c# - Linq 实体分组依据(外部应用) "oracle 11.2.0.3.0 does not support apply"

c# - 最接近数字的linq sql

c# - 正则表达式匹配 4 个 float

C# 创建通用实例