【问题标题】:Expression Tree Cast to ICollection<T> & Add表达式树转换为 ICollection<T> 并添加
【发布时间】:2017-06-20 18:02:26
【问题描述】:

我需要创建一个非常有效且重复的动作:

  1. 将对象类型变量转换为 ICollection 类型变量
  2. 将对象类型变量转换为 T 类型变量
  3. 将 T 类型项添加到 ICollection 类型集合中。

据我了解,构建表达式树并存储操作以供重用是最快的方法。我有很多麻烦。为了更清楚地说明这一点,我需要一个表达式树编译操作来执行此操作:

private void AddToCollection(Type itemType, object item, object collection)
{
    // assume itemType is used in the expression-tree to cast to ICollection<T>
    ((ICollection<T>)collection).Add((T)item);
}

【问题讨论】:

  • 为什么不直接使用泛型函数呢?使用表达式能给你什么?
  • Type itemType 参数是不可能的。唯一可能的是为特定的Type 创建Action&lt;object, object&gt;,然后通过object item, object collection 多次调用它。它对你有用吗?
  • @Amy 我不能使用泛型方法,因为我没有类型参数。我已经使用反射从标有属性的属性派生了集合的实例。
  • @IvanStoev 是的,这可行。我可以为我需要的每种类型缓存一个新操作。

标签: c# expression-trees


【解决方案1】:

不可能高效地创建非反射代码

private void AddToCollection(Type itemType, object item, object collection)
{
    // Assume that itemType became T somehow
    ((ICollection<T>)collection).Add((T)item);
}

因为为了避免反射,Type 必须事先知道(具体或泛型类型参数)。

虽然可以创建这样的东西:

static Action<object, object> CreateAddToCollectionAction(Type itemType)
{
    // Assume that itemType became T somehow
    return (item, collection) => ((ICollection<T>)collection).Add((T)item);
}

方法如下:

static Action<object, object> CreateAddToCollectionAction(Type itemType)
{
    var item = Expression.Parameter(typeof(object), "item");
    var collection = Expression.Parameter(typeof(object), "collection");
    var body = Expression.Call(
        Expression.Convert(collection, typeof(ICollection<>).MakeGenericType(itemType)),
        "Add",
        Type.EmptyTypes,
        Expression.Convert(item, itemType)
    );
    var lambda = Expression.Lambda<Action<object, object>>(body, item, collection);
    return lambda.Compile();
}

示例用法:

var add = CreateAddToCollectionAction(typeof(int));
object items = new List<int>();
add(1, items);
add(2, items);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    相关资源
    最近更新 更多