1

如何在一组通用 C# 类型上重用 LINQ 聚合查询,这些类型具有在编译时已知的通用形状或接口,而不诉诸黑魔法动态ExpressionBuilder内容?

例如,

// Each "reportable" class has a decimal property to sum over:
interface IReportable<T> {
    Expression<T, decimal> GetSummingExpr(); // no static interface methods :(
}

public static class ReportingExtensions {
    public static IQueryable<decimal> Report<T>(this IQueryable<T> qry)
    {
        return x => x.Sum(qry.GetSummingExpr()); // unsure if interfaces can do this
    }
}

var invoices = new Invoice [] { Invoice(100.0M), ... };
var quotes = new Quote [] { Quote(50.0M), ... };

// Ideal use-cases:
var invoiceReport = invoices.AsQueryable().Report();
var quoteReport = quotes.AsQueryable().Report();

// "Reportable" class implementations:
public class Invoice : IReportable<Invoice>
{
    public decimal InvoiceTotal { get; set; }

    public Expression<Func<Invoice, decimal>> GetTotalExpr()
    {
        return x => x.InvoiceTotal;
    }
}

public class Quote : IReportable<Quote>
{
    public decimal QuoteTotal { get; set; }

    public Expression<Func<Quote, decimal>> GetTotalExpr()
    {
        return x => x.QuoteTotal;
    }
}

我尝试了各种方法,但是如果不引入魔术字符串,我就无法让它工作,ala x.GroupBy("InvoiceTotal")

据我所知,这很难,因为 LINQ 类型在泛型“渲染”为“具体类型”之前就已解决。但是,所有类型签名在编译时都是已知的,因此我应该能够强制编译器执行此操作。

4

0 回答 0