`
RednaxelaFX
  • 浏览: 3053150 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

.NET Framework 4.0 Beta 1里的Expression Tree一例

    博客分类:
  • DLR
阅读更多
既然装上了Visual Studio 2010 Beta 1,正好可以试试.NET Framework 4.0里的一些新东西。我比较关注的是Expression Tree的部分,到底哪些功能进到了.NET 4,哪些还得到CodePlex的DLR站上去找呢?试用一下找找感觉。

我暂时没试这个beta里的C#对dynamic的支持,是因为暂时还没想到啥有趣的场景能写点简单的代码来玩的。对.NET类型故意使用dynamic的玩法在之前CTP的时候就玩过了,不过瘾了。回头针对.NET 4来编译一个IronPython来看看,到时就能好好把玩一番dynamic了。

回到Expression Tree。在.NET Framework 4.0里它叫Expression Tree v2,简称ETv2。它兼容于.NET Framework 3.5里LINQ的Expression Tree,但实际上是从DLR的DLR tree发展而来的。时至今日DLR的代码仍在快速变化中,而ETv2作为LINQ与DLR的公共部分要放到标准库里,等不到DLR稳定下来。折中的解决方案就是在标准库里的版本砍掉一些DLR里还没定下来的东西和低优先级的东西。像是LoopExpression进入了标准库,但特化版本的ForEach、While等就只有CodePlex上的版本才有。
.NET Framework 4.0中,ETv2位于System.Core.dll程序集中,在System.Linq.Expressions命名空间下。CodePlex的DLR的ETv2则位于Microsoft.Scripting.Core.dll程序集中,Microsoft.Linq.Expressions命名空间下。CodePlex的DLR之所以要用不同的命名空间是为了避免与标准库冲突,但这样一来由编译器生成的ET就与CodePlex的DLR中的ET不兼容了。所以我才那么期待.NET 4.0赶紧出……为了能用上标准库里的ETv2。

昨天装好VS2010 Beta后写的代码如下。

就是先做了个简单的in-memory LINQ查询,然后用ETv2来构造出一个遍历并输出查询结果的函数,并调用之。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace ConsoleApplication1 {
    static class Program {
        static void Main(string[] args) {
            var list = from i in Enumerable.Range(0, 100)
                       where i % 9 == 0
                       orderby i descending
                       select i;
            var vIter    = Expression.Variable(typeof(IEnumerator<int>), "iter");
            var vI       = Expression.Variable(typeof(int), "i");
            var lBreak   = Expression.Label();
            var eForeach = Expression.Lambda<Action>(
                Expression.Block(
                    new[] { vIter, vI },       // IEnumerator<int> iter; int i;
                    Expression.Assign(         // iter = list.GetEnumerator();
                        vIter,
                        Expression.Call(
                            Expression.Constant(list),
                            typeof(IEnumerable<int>).GetMethod("GetEnumerator"))),
                    Expression.Loop(           // while (true)
                        Expression.IfThenElse(     // if
                            Expression.Call(           // (iter.MoveNext())
                                vIter,
                                typeof(IEnumerator).GetMethod("MoveNext")),
                            Expression.Block(          // {
                                Expression.Assign(         // i = iter.Current;
                                    vI,
                                    Expression.Property(vIter, "Current")),
                                Expression.Call(           // Console.WriteLine(i);
                                    typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }),
                                    new[] { vI })),
                            Expression.Break(lBreak)), // } else break; }
                        lBreak)),
                new ParameterExpression[0]);
            eForeach.Compile()();
        }
    }
}


用ETv2构造出来的函数基本等价于一个含有普通foreach循环的lambda:
() => {
    foreach (var i in list) {
        Console.WriteLine(i);
    }
}

注意到foreach循环可以被展开为while循环:
() => {
    var iter = list.GetEnumerator();
    while (iter.MoveNext()) {
        var i = iter.Current;
        Console.WriteLine(i);
    }
}

我用ETv2实现的lambda实际上是这样的:
() => {
    var iter = list.GetEnumerator();
    int i;
    while (true)
        if (iter.MoveNext()) {
            i = iter.Current;
            Console.WriteLine(i);
        } else
            break;
}

后来想了想,我应该把vI放在if里的block来声明的,会更符合foreach的语义。不过懒得开虚拟机去改了……
写成while (true)是因为ETv2里的LoopExpression就是代表一个无限循环,外加用户可自定义的条件分支及跳转目标(BreakTarget和ContinueTarget)。在C-like语言里,基本循环结构可以分为条件前置的while/for和条件后置的do...while两种。但总有些时候我们希望既不是在开头也不是在结尾,而是在循环体的中间来判断循环条件;在C-like语言里我们就只好用无限循环+条件语句来模拟这种半中腰的循环结构。ETv2为了提供最大的弹性,提供的基本循环结构就是这种代表无限循环的LoopExpression。但这样的基本结构用起来总让人嫌麻烦,还好CodePlex上的DLR里有特化版本的循环结构,只是没赶上.NET 4这趟车而已。
1
0
分享到:
评论

相关推荐

    .Net Framework 4.0 目标包

    .Net Framework 目标包是VS2019开发下载的目标包,包括.net framework3.5 、 .net framework4.0 、 .net framework4.5 vs2022使用.Net Framework4.0方法:,将上述.Net Framework包直接复制粘贴到如下目录下即可:C...

    .net framework 4.0离线安装包_dotNetFx40_Full_x86_x64

    安装过程中,.NET Framework 4.0会添加一系列核心组件,包括Common Language Runtime (CLR),这是.NET Framework的基础,负责执行.NET程序;以及类库集合,这些类库提供了大量预定义的功能,如数据访问、网络通信、...

    Microsoft .NET Framework 4.0 Beta 1

    .NET Framework 4.0 Beta 1是微软发布的一个重要的软件开发平台,用于构建、运行基于Windows操作系统的应用程序。这个版本的.NET Framework引入了许多新特性和改进,旨在提高开发者的工作效率和应用程序的性能。以下...

    .net framework4.0离线版安装包,解决证书过期问题

    .NET Framework 4.0离线版安装包是一个重要的软件组件,尤其对于那些无法连接到互联网或者需要在没有网络环境的计算机上安装此框架的用户来说,它提供了便捷的解决方案。这个离线安装程序包含了所有必要的组件,使得...

    .NET Framework 4.0.30319

    .NET Framework 4.0.30319是微软开发的一个关键组件,它为Windows操作系统上的应用程序提供运行环境。这个版本的.NET Framework是.NET Framework 4系列的一部分,它包括了大量的新特性和性能优化,旨在提升开发者...

    Kafka .Net Framework4.0 版本

    在.NET Framework 4.0环境下,我们可以使用Kafka的.NET客户端库来与Kafka集群进行交互。本篇将详细介绍Kafka .Net Framework 4.0版本以及其相关知识点。 首先,Kafka .Net是.NET社区开发的一个C#和F#接口,它为.NET...

    .net framework 4.0安装环境

    .NET Framework 4.0是微软开发的一个重要软件框架,它为开发者提供了构建、运行Windows应用程序所需的类库和服务。这个框架自2010年发布以来,已经成为开发Windows桌面应用、Web应用以及服务的重要基础。本篇文章将...

    .NET Framework 4.0 离线安装包

    .NET Framework 4.0是微软开发的一个至关重要的软件开发框架,它为程序员提供了构建、运行基于Windows的应用程序所需的各种工具和服务。这个离线安装包,名为"dotNetFx40_Full_x86_x64.exe",包含了适用于32位(x86...

    .NET FrameWork 4.0.30319

    .NET Framework 4.0.30319是微软开发的一款重要的软件开发框架,它为开发者提供了构建、部署和运行Windows应用程序所需的环境。这个版本的.NET Framework是在2010年发布的,它在.NET Framework 4的基础上进行了更新...

    office 2016安装.NET Framework4.0失败

    ### Office 2016 安装 .NET Framework 4.0 失败问题解析及解决方案 #### 一、问题背景 Office 2016 在安装过程中有时会遇到依赖于 .NET Framework 4.0 的组件安装失败的问题。根据描述,用户在使用 Win7 操作系统...

    .NET Framework4.0.30319

    2. Microsoft.NET4.0.30319.exe:这个文件很可能是.NET Framework 4.0的完整安装程序,如果系统中没有4.0版本,需要先安装这个文件,才能继续安装kiwi syslog server所需的4.0.30319更新。 总结来说,.NET ...

    .NET4.0离线安装包

    总的来说,`.NET4.0离线安装包` 提供了一种方便的方式,让用户在无网或低速网络条件下也能安装和使用.NET Framework 4.0,从而能够运行基于该框架开发的各种应用程序。对于开发者而言,了解.NET Framework 4.0的新...

    VS2022无法安装.net Framework4.0解决办法

    在使用Visual Studio2022会遇到无法安装.NET Framework 4.0的问题。这个问题可能由多种原因导致,包括但不限于系统兼容性、已安装的其他软件冲突或者缺少必要的更新。本文将详细讲解如何安装.NET Framework 4.0来...

    .net framework 4.0 简体中文语言包

    好多人在照这个东西吧,赫赫。 至于是什么东西,编程的人都知道的。 Microsoft dotNet framework 4.0 简体中文语言包 Microsoft .net framework 4.0 简体中文语言包

    Newtonsoft.Json .net framework 3.5 和.net framework 4.0两个版本

    总结来说,Newtonsoft.Json 是一个强大的 JSON 库,它提供了针对 .NET Framework 3.5 和 4.0 的版本,以满足不同开发环境的需求。通过其丰富的 API,开发者可以方便地进行 JSON 序列化、反序列化以及动态数据操作,...

    .net FrameWork4.0安装包

    .NET Framework 4.0是微软开发的一个重要软件框架,它为开发者提供了构建、运行各种Windows应用程序所需的类库和服务。此框架是.NET战略的核心部分,它包括了编程模型、基础类库以及对Web服务的支持,使得开发者能够...

    由于未安装.net framework 4.0的miscrosoft office支持,无法加载以下解决方案 ***.vsto

    标题中的问题指向的是一个特定的软件兼容性问题,即在尝试加载某个Visual Studio Tools for Office (VSTO)开发的解决方案时,由于缺少.NET Framework 4.0导致失败。这通常发生在试图运行由VSTO编译的Office插件或...

    Newtonsoft.Json .net framework4.0版

    **Newtonsoft.Json .NET Framework 4.0版** 在.NET开发中,序列化和反序列化JSON数据是一项常见的任务,而Newtonsoft.Json库是.NET生态系统中最流行和广泛使用的JSON处理库之一。该库由James Newton-King 开发,...

    [其他类别]Microsoft .NET Framework 4.0 Beta 1 (x86)_dotnetfx40_full

    Microsoft .NET Framework 4.0 Beta 1 是微软公司推出的一款重要软件开发平台,它为开发者提供了构建、部署和运行各种应用程序的强大支持。尤其值得注意的是,这个版本是针对x86架构的,这意味着它主要面向32位操作...

Global site tag (gtag.js) - Google Analytics