如何将Enumerable <t>。Where(谓词)的实例转换为IEnumerable <t>?</t> </t>

时间:2011-07-18 05:25:41

标签: c# .net linq c#-4.0 ienumerable

我正在编写一个c#代码生成器。在某些地方,我必须将类似WhereSelectListIterator的Linq方法的返回类型转换为IEnumerable类型。我该怎么办?

方案: 我有一个名为aList的List实例。我在文本框中写下面的表达式:

aList.Where(item => item.StartsWith("s")).Select(item => item.ToUpper()).ToList().Count

我需要编写一个应用程序来评估我的表达式。我知道我必须编写一个C#代码生成器来评估我的表达式。 如果我直接评估上面的表达式它是有效的。但是假设我有以下情况:

public Interface IInterface
{
}
public class MyClass:IInterface
{
    public int Id = 10;
    public IInterface GetInstance()
    {
        return new MyClass();
    }
}

public class Program
{
    public static void Main()
    {
        var myClass = new MyClass();
        myClass.GetInstance().Id.ToString();
    }
}

当我在调用GetInstance()方法后使用Id属性时,它会导致CLR引发异常,因为IInterface没有Id属性。我需要首先将返回类型的GetInstance()强制转换为MyClass,然后使用Id属性。 我该怎么做动态演员。 一种解决方案是使用动态对象。

var myClass = new MyClass();
dynamic x = myClass.GetInstance();
dynamic y = myClass.Id;
y.ToString();

但是动态对象有扩展方法的问题(例如:Where(),Take(),...)。我该怎么办?

2 个答案:

答案 0 :(得分:1)

回答你在标题中提出的问题,Enumerable<T>.Where(Predicate)实施IEnumerable<T>的结果,只是施展它,不需要做任何花哨的事情。见这里:Enumerable..Where(TSource) Method (IEnumerable(TSource), Func(TSource, Boolean))

至于其余部分,为什么要尝试生成C#代码?如果您正在尝试评估在运行时输入的代码片段,为什么不使用C#编译器进行编译呢?我用Google搜索“C#编程编译”,第一个结果是这个Microsoft支持页面:How to programmatically compile code using C# compiler

答案 1 :(得分:1)

您可以在dynamic个对象上调用扩展方法,如下所示:

dynamic result = Enumerable.Where(collection, (Func<dynamic, bool>)delegate(dynamic item)
                                              {
                                                   return item.Id == id;
                                               });