【问题标题】:Can't convert ICollection<t> to IEnumerable<t>无法将 ICollection<t> 转换为 IEnumerable<t>
【发布时间】:2019-02-08 08:52:49
【问题描述】:

我正在构建表达式树:

{x => x.principal_info.First().agent_for_property_info}

它按预期工作。

事实上,我需要将其转换为IEnumerable 而不是ICollection,如您在此处看到的那样。

下面是有效的方法:

public Expression<Func<T, IEnumerable<K>>> GetGenericExpression<T, K>(bool first = false, params string[] properties)
    {
        var expression = GetNavigationPropertySelector<T, K>(typeof(T), first, properties);

        var expRight = (Expression<Func<T, IEnumerable<K>>>)expression;

        return expRight;
    }

在表达式中,我得到了有效的 lambda 表达式:

{x => x.principal_info.First().agent_for_property_info}

当我投射时:

var expRight = (Expression<Func<T, IEnumerable<K>>>)expression;

我得到一个例外:

Unable to cast object of 
type 
'System.Linq.Expressions.Expression`1[System.Func`2[SomeModel1,
System.Collections.Generic.ICollection`1[SomeModel]]]' 
to type 
'System.Linq.Expressions.Expression`1[System.Func`2[SomeModel1
,System.Collections.Generic.IEnumerable`1[SomeModel]]]'.

我知道ICollection 继承自IEnumerable,假设它很容易修复。

我进行了很多研究,但没有找到解决方案如何将 ICollection&lt;T&gt; 转换为 IEnumerable&lt;T&gt; 或者这是否可能?

事实上,编译器可以隐式转换它,因为这些行是有效的:

var queryData1 = new QueryData<contact_info, IEnumerable<property_info>>()
                {
                    WhereClause = expression,
                    SelectClause = info => info.principal_info.First().agent_for_property_info
                };

因为这个表达式是ICollection的一个类型:

info => info.principal_info.First().agent_for_property_info

【问题讨论】:

  • @Adriani6 我们的问题在某些情况下有所不同:1)重点是从 IEnumerable 转换为 ICollection(我的情况:反之亦然) 2)他们正在尝试转换实际数据集 - 在我的情况下我需要正确类型的表达式。
  • 你是对的,我撤回了我的投票:)
  • 不,您没有尝试将ICollection&lt;T&gt; 转换为IEnumerable&lt;T&gt;。您正在尝试转换(在一两次手波内)一个 delegate 将产生 ICollection&lt;T&gt; 您不需要投射 it,您需要投射它产生了一个结果,这表明您将在这里编写(部分)表达式树以实现您想要的(如果那是您想要走的路线)
  • @Damien_The_Unbeliever 是的,你是对的。只是转换结果类型。
  • @DanielLoudon lambda 表达式没有像 'select' 这样的扩展方法 Expression>>。

标签: c# expression ienumerable expression-trees icollection


【解决方案1】:

经过几个小时的研究,尝试了不同的方法,我想出了 Idea,试图克服这个例外。所以我使用的解决方法是来自 cmets 的建议:

x => x.principal_info.First().agent_for_property_info.Select(x4 => x4)

这是我在构建表达式时添加的内容:

var result1 = Expression.Call(
                    typeof(Enumerable), "Select", new Type[] { elementResultType, elementResultType },
                    resultProperty, resultExpr);

其实我没有找到解决办法,但是如果有人遇到这样的问题,也许这个答案可以节省他的时间。

【讨论】:

  • 我无法使用您的解决方法,但我必须感谢您回来与我们分享您的发现!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-24
  • 2021-12-02
相关资源
最近更新 更多