如何将 Enumerable.Where(Predicate) 实例强制转换为 IEnumerable

发布于 2024-11-24 20:15:17 字数 1037 浏览 5 评论 0原文

我正在编写 ac# 代码生成器。在某些地方,我必须将 Linq 方法的返回类型(如WhereSelectListIterator)转换为 IEnumerable 类型。我该怎么做呢?

设想: 我有一个名为 aList 的列表实例。我在文本框中编写以下表达式:

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() 等)。我能做些什么?

I'm writting a c# code generator. In some place I must cast return type of Linq's method like WhereSelectListIterator to IEnumerable type. How can I do it?

Scenario:
I have an instance of a List named aList. I write following expression in a Textbox:

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

I need to write an application to evaluate my expression. I know that i must write an C# code generator to evaluate my expression.
If I evaluate above expression directly it is works. But suppose that I have following scenario :

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();
    }
}

When I use Id property after calling GetInstance() method it cause to CLR raise an exception because IInterface hasn't Id property. I need to cast return type of GetInstance() to MyClass first then use Id property.
How can I do this cast dynamically.
One solution is using dynamic object.

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

But dynamic object has problem with Extension methods(ex : Where(), Take() , ...). What can I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

-残月青衣踏尘吟 2024-12-01 20:15:17

回答您在标题中提出的问题, Enumerable.Where(Predicate) 的结果实现了 IEnumerable,只需强制转换即可,无需进行转换做任何花哨的事情。请参阅此处: Enumerable..Where(TSource) 方法 (IEnumerable(TSource), Func( TSource, Boolean))

至于其余的,为什么要尝试生成 C# 代码?如果您尝试评估在运行时输入的代码片段,为什么不使用 C# 编译器来编译它呢?我在 Google 上搜索“C# 编程编译”,第一个结果是 Microsoft 支持页面:如何使用以下代码以编程方式编译代码C#编译器

In answer to the question you ask in the title, The result of Enumerable<T>.Where(Predicate) implements IEnumerable<T>, just cast it, no need to do anything fancy. See here: Enumerable..Where(TSource) Method (IEnumerable(TSource), Func(TSource, Boolean))

As for the rest, why are you trying to generate C# code? If you're trying to evaluate a code snippet that was entered at runtime, why not use the C# compiler to compile it? I Googled for "C# programmatic compilation", and the first result was this Microsoft support page: How to programmatically compile code using C# compiler

零度℉ 2024-12-01 20:15:17

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

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

You can call extension methods on dynamic objects like this:

dynamic result = Enumerable.Where(collection, (Func<dynamic, bool>)delegate(dynamic item)
                                              {
                                                   return item.Id == id;
                                               });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文