【问题标题】:Create Func<T, TKey> dynamically动态创建 Func<T, TKey>
【发布时间】:2019-04-22 11:03:47
【问题描述】:

相关话题:

Create Expression&lt;Func&lt;T, TKey&gt;&gt; dynamically

我在互联网上搜索,但所有示例都解释了Expression&lt;Func&lt;。如何从T 动态创建Func&lt;T, TKey&gt;?

谢谢


编辑 1)

我的代码中的T 类型在运行时确定,例如我想用Name 对我的列表进行排序。现在我如何创建这个:Func&lt;T, TKey&gt; = o=&gt;o.Name;


编辑 2)

请考虑一下:

public abstract class MyClass<T> where T : class
{
    public virtual List<T> GetAll(Expression<Func<T, bool>> exp, string orderByProperty)
    {
         repository.Get(exp).OrderBy(?);
    }
}

问题是创建一个Func&lt;T, TKey&gt; 以在OrderBy 参数中使用。如何使用Name 属性对列表进行排序?

谢谢

【问题讨论】:

  • 请编辑您的问题以详细说明“动态”。你想做什么?你试过什么?什么没有按预期工作?
  • 这听起来像XY problem。你能通过创建一个Func&lt;&gt; 对象来详细解释你想要做什么吗?您需要在哪里提供这些信息?你想让我做什么?你打算如何做你想做的事?请在您的问题中扩展描述/问题。
  • 听起来您需要找到正确的PropertyInfo,从中获取合适的getter 方法,然后调用Delegate.CreateDelegate。如果您可以提供 minimal reproducible example 来说明您想要实现的目标,那么检查并提供答案会更容易。
  • @Arian 你仍然缺少minimal reproducible example。最后一次编辑本身并没有帮助。它本身不会编译,但假设它是泛型类的一部分。但这是一种假设,无助于为您提供相关的解决方案。
  • 有问题的方法如何知道要订购的属性?例如Name(而不是FooBar)来自哪里?类和方法都没有指示。此外,如果它是string,那么在 SO 上有几种解决方案 - stackoverflow.com/questions/39908403/…、stackoverflow.com/questions/8398453/… 等。

标签: func dynamic-linq c#-7.0


【解决方案1】:

鉴于抽象类的定义,您需要在泛型参数中包含键,以便能够使用它。

通过函数传递订单的简单示例。

public abstract class MyClass<T, TKey> where T : class {
    public virtual List<T> GetAll(
        Expression<Func<T, bool>> exp, 
        Func<T, TKey> keySelector = null
    ) {
        var query = repository.Get(exp);

        if(orderBy != null) {
            return query.OrderBy(keySelector).ToList();

        return query.ToList();
    }
}

然后您可以使用默认键类型的类的派生版本

例如,以下使用 string,但也可以很容易地使用 int、Guid 等。

public abstract class MyClass<T> : MyClass<T, string> where T : class {

}

但底线是您需要按类型知道顺序才能使用它。

...GetAll(_ => _.SomeProperty == someValue, o => o.Name);

【讨论】:

  • 这是不可能的,因为我有另一种方法,他们应该使用其他列对记录进行排序
  • @Arian 你明白我没有minimal reproducible example 的意思。我们怎么会知道呢?此建议是根据给定信息提供的。
【解决方案2】:

如果你想一路动态,你可以使用System.Linq.Dynamic.Core

class SomeClass
{
    public int SomeValue { get; set; }

    public int X { get; set; }
}

public class MyClass
{
    public static List<T> GetAll<T>(string predicate, string orderByProperty)
    {
        var repository = new List<SomeClass>() {
            new SomeClass{SomeValue = 1, X = 12 },
            new SomeClass{SomeValue = 2, X = 99 },
            new SomeClass{SomeValue = 3, X = 55 }
        }.AsQueryable();

        return repository.Where(predicate).OrderBy(orderByProperty).ToDynamicList<T>();
    }
}

void Main()
{
    var result = MyClass.GetAll<SomeClass>("SomeValue > 1", "X");
    result.Dump();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    相关资源
    最近更新 更多