把我的爱送给你――C#3.5(这题目似乎写错了)

本文发表于 中国IT实验室周报。这是我初次写给杂志社稿件,其中必有许多不足之处,还望大家见谅,虽然这篇文章质量可能不太高,但我希望能将个人的这些总结与大家分享。

 

从笔者接触编程至今,经历了数种编程语言,从Visual Basic6.0桌面程序开发到ASP(VBScript)的网站开发,从C#1.1到C#2.0,再至今日的令人加心动的C#3.5,笔者曾多次为Windows平台下的编程感慨——越来越方便的操作,越来越强大的功能,越来越简洁的代码使得由代码组成的编程世界中平添的许多色彩与欢乐。

以上可以算作对即将要介绍的C#3.5新特性的一个铺垫。笔者对于C#的爱,胜过其他的任何语言,尤其对于刚刚召开不久的微软2008新技术大会上发布的Visual Studio 2008笔者的爱意更甚。于是,笔者决定将自己对它的爱以文章的形式来表达。

让我们去由此开始,向C#3.5示爱:

一、告诉C#3.5,我们对爱上它的暧昧-var关键字

暧昧?众所周知,C#从出生以来都是很以一种强类型的语言示人的,并不像JavaScript和VB6.0那样给人以“暧昧”的感觉啊?而在此处介绍的关键字var,是否让您想起了JavaScript中的定义变量的关键字var?事实上,这两个看似相同的关键字却有本质上的区别。而这个var关键字并非在C#3.5中才出现的,它在C#3.0中便已经存在,笔者之所以在此介绍它,是因为欲介绍3.5,必须而且应该去介绍一下这个在C#3.0中便出现的特性——本地类型推断(Local Type Reference),如若不然,笔者内心便无法安稳。

在C#2.0及其以前的版本中,如若定义一可以向其赋任何值的变量,那么我们需对其以object关键字进行定义,这种变量需要对值类型的进行装箱操作而且在对该变量使用的时候还需要进行相应的拆箱操作,而这种装箱拆箱所耗费的资源实在是笔者所不愿意看到的。

那么,我们既不愿意编写无谓耗费资源的代码,又想去实现object定义变量实现的功能,怎么办?C#3.5为我们提供了一种变量定义方式:

(图1,1.jpg)

clip_image002

看上面的变量定义,奇怪么?其实这就是C#3.5为我们提供的一种新功能——本地类型推断,它可以保护类型安全,而且允许您编写更为“自由”的代码。也就是说,我们可以不去考虑变量的类型而直接以var关键字去修饰它,编译器能够从给变量赋值的表达式中智能推断出变量的类型。它和COM模型中的Variant关键字定义出的变量完全不同,COM中的Variant关键字是后期绑定的一种方式,在编译期没有检测,仅在代码运行时才会出现它自身存在的问题,而且一不小心就会出现一大堆令人讨厌的Bug。而C#中这个var定义的变量在编译其便推断出它的类型,并且编译后的IL代码中只包含推断出的类型。

即上面的两行代码完全等同物如下代码:

(图二,2.jpg)

clip_image004

那么,既然二者等同,我们为什么还要对它的这种“暧昧”情有独衷?事实上,var关键字不仅仅能够实现我们如上所述的功能,它会成为你在使用C#3.5进行编程时非常熟悉的一个朋友,记住这个“匿名类型(Anonymous Type)”,也记住这个“本地类型推断(Local Type Reference)”。

二、告诉C#3.5,我们喜欢它纤细的身材——自动属性(Automatic Properties)

还记得我们在C#1.1和C#2.0写类的属性时定义的那个小小的私有变量么?甚至有些人还因为私有变量是否应该和属性定义在一起而展开了争论。那么,现行社会流行的“减肥”这个词也可以应用到我们的程序代码上来。

C#3.5为我们提供了自动属性(Automatic Properties),看如下代码:

(图三,3.jpg)

clip_image006

很奇怪么?get和set关键字均没有我们以前所熟悉的return value;和_privateField=value;这样的字眼。事实上,这就是我们的这善解人意的代码编译器为我们提供的最新功能自动属性。编译器会为我们定义的Name属性自动生成一私有变量来保存其值。于是,我们原来需要至少三行才能完成的代码现在仅需一行便轻松完成了。

不过,它有自身的局限性,比如说不能在用自动属性定义的属性中加逻辑判断,get和set必须成对出现等。然而,笔者相信并非我们所有的属性均要加上逻辑判断吧?那么,就请去尝试自动属性为我们带来的便利。

三、奇怪的“=>”符号——lambda表达式

习惯C#编程的您在C#2.0及其以前见到过这个符号”=>”么?这又是一新特性,我们可以将它读作”lambda表达式”。

C# 2.0 通用使用匿名方法引入了"传递指针到特定代码"作为参数的功能。这是一个功能强大的概念,但是这种方式您实际传递的是方法的一个指针,而不是代码块。那个引用指向编译时生成的强类型代码。使用泛型,您可获得更大灵活性,但是对泛型类型难以应用标准操作符 。C# 3.0 引入 lambda 表达式,它允许使用更简练的语法来定义匿名方法。

看如下代码片断:

(图四,4.jpg)

clip_image008

且不说其他部分意义,单来看我们.Where括号之中的部分,c=>c.Address==City.Heze这段代码,我们可以将它理解为,给定c,返回c.Address==City.Heze的记录集,此处就是lambda表达式的应用之一,它广泛应用于我们下期即将介绍的LINQ(Language Integerated Query)中。

四、为我们的爱加上更为自由的翅膀——扩展方法

熟知Web编程的朋友们应该对如下这段代码很熟悉:

(图五,5.jpg)

clip_image010

其中ReplaceUnSafeChars是一个进行字符器过滤的函数,将传入的字符串中的非法字符过滤,返回一合法的字符串,它通常用于用户向某一数据处理页面提交数据时,为了防止SQL注入或者其他非法入侵而进行的一项工作。为此我们不厌其烦地写类库,在某一项目的解决方案中添加进来自己过滤函数。这种方式是不错,可是,能不能有一种方式让我们更为方便,让我们写出的代码更为优雅?

设想,如果我们能够对系统中定义的数据类型进行扩展,给它增加上我们自己的方法,那岂不是我们可以像strID.ToSring()那样来实现我们自己的过滤方法?

不错,想法有了,自然C#也不会让我们失望——扩展方法(Extension Methods)为我们来解决这一问题。如下图我们定义一个类:

(图六,6.jpg)

clip_image012

注意,该类为静态类,并且其中的方法Name为静态方法,其参数o为object类型,并且有关键字this进行修饰。以上这些,就是为系统类型进行扩展时的必备条件。在定义了该类的同一命名空间下的其他类中即可对所有类型使用该Name方法来获取它的ToString()之后的值。我们看编译器是如何来表示的:

(图7,7.jpg)

clip_image014

我们看到,编译器强大的智能提示功能给我们的提示是(extension) string object.Name(),这是因为我们是对object类进行了扩展,故我们可以对任何类型使用扩展方法Name。

这虽然并不是一个十分大的改动,可是对于我们在代码上的可读性及实用性都会有很大的帮助。我们习惯了从左到右的阅读方式,习惯了在打”.”时编译器给出智能提示,所以我们也会毫无理由的习惯“扩展方法”。

要注意,对于值类型的变量进行扩展是MS推荐的,可是对于引用类型的变量进行扩展却并未被推荐,因为对于所有的调用都要创建一个对象的拷贝,而这个对象拷贝的创建的花销是我们所不敢随意忽略的。

五、令人心动的LINQ

您想过在代码中不写SQL语句就实现对数据库的操作么?当然,笔者并不是指那种通过拖拽数据源控件如SQLDataSource等然后加个GridView或者FormView就去实现对数据的显示、更新的操作。假如有一种工具能够让将我们数据库中的表映射为对象,而且映射这一工作能够自动完成,然后我们就可以通过对这些映射过来的对象进行操作,从而实现对数据表的操作了。

正如笔者上面所说,想法有了,就可以实现。事实上,LINQ并不是属于C#的,更不能说是C#3.5的特性了。不过笔者在这里提出,主要是因为它实在太令人兴奋而且C#3.5中的编程如果没有了对LINQ的使用代码就会逊色许多。

上述两段作为您的“开胃菜”,仅令您心动是远远不够的,让我们近距离接触一下LINQ——语言集成查询(Language Integerated Query)。

笔者以LINQ对数据库的操作来对LINQ做一下大概的介绍。

LINQ to SQL 是O/RM(对象关系映射)在.NET Framework(Visual Studio 2008)中的的一种实现,它允许你用.NET 的类来生成一个关系型的数据库。然后你可以用LINQ对从该对象中对数据库进行查询,更新/插入/删除。

LINQ to SQL完全支持事务,视图和存储过程。它还提供了一种方便地在你的数据模型中对集合数据验证和业务逻辑规则的进行验证的方法。

它的基本语法from… in..select是显得如此优雅,令我不得不为其用如此简洁的代码实现我们以往需要写数行甚至数十行才能够实现的功能感到兴奋。还记得我们在上面介绍“=>”lambda表达式时提供的那个小例子么?

(图8,8.jpg)

clip_image008[1]

这就是最简单的LINQ实现。其中customers可以是我们从数据库中映射过来的对象,也可以是我们自己定义的某类的实例。它实现的功能是从customers对象实例中查找出所有的Address为Heze的实例,返回值IEnumerable<Customer>类型。LINQ可以实现对所有实现了IEnumuerable接口的对象进行查询

事实上,LINQ不仅可以to DataSet,也不仅可以to SQL,也不仅可以to XML,笔者认为,LINQ是可以to Everything的。

结语

以上仅仅是给笔者很大触动并且打动了笔者心的若干功能的一部分,限于篇幅笔者不能一一进行展开,望读者见谅。笔者将在后续的文章中与您分享更多的知识与经验。

转载于:https://www.cnblogs.com/hanxianlong/archive/2008/05/15/1196459.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300399.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Blazor 数据绑定开发指南

翻译自 Waqas Anwar 2021年3月21日的文章 《A Developer’s Guide to Blazor Data Binding》 [1]现如今&#xff0c;大多数 Web 应用程序要么是在页面上显示某种数据&#xff0c;要么是使用表单从用户那里收集数据。这意味着每个 SPA 框架都必须支持数据绑定&#xff0c;以便开…

葛优:你们有看过我的作品吗?| 今日趣图

全世界只有3.14 % 的人关注了青少年数学之旅

阳江海滩景色一瞥

前几天同学去阳江的海边玩了2天&#xff0c;海景相当不错&#xff0c;不敢独享&#xff0c;特来贴图。 转载于:https://www.cnblogs.com/absolute8511/archive/2008/05/24/1649638.html

使用表达式自定义Serilog输出格式

Serilog是.NET Core中常用的结构化日志类库&#xff0c;透过logging API可以轻松的记录应用程式中对象属性&#xff0c;方便快速进行logging内容进行查询与分析&#xff0c;并将其记录内容通过指定方式输出。今天&#xff0c;介绍一个Nuget包Serilog.Expressions&#xff0c;它…

那些不回微信的人,都在看什么?

全世界只有3.14 % 的人关注了青少年数学之旅有人统计过&#xff0c;我们平均每天花在看内容上的时间是5-6小时&#xff0c;只要拥有一个手机&#xff0c;我们似乎无所不知。但&#xff0c;你是否还记得昨天都看了哪些内容&#xff1f;你能将它们一一都说出个大概吗&#xff1f;…

怎样让WinForms下DataGrid可以像ASP.NET下的DataGrid一样使用自定义的模板列

昨天被问到一个问题&#xff1a;怎么把WinForms里的DataGrid的绑定了数据库bit字段的列默认显示的CheckBox换成“男”和“女”&#xff0c;也就是说怎么样像ASP.NET的模板列那样可以自定义。&#xff08;此处不考虑在SQL在用Case把数据结果转换了&#xff09;由于&#xff0c;基…

智能优化算法应用:基于原子轨道搜索算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于原子轨道搜索算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于原子轨道搜索算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.原子轨道搜索算法4.实验参数设定…

dotnet中的counters说明(三)

本篇分别说明一下System.Net下的Http计数器&#xff0c;NameResolution计数器&#xff0c;Security计数器和Sockets计数器。同时&#xff0c;下面指标各项()里的项目是--counters 参数[]里的项&#xff0c;用逗号分隔多项指标。System.Net.Http计数器以下计数器由 HTTP 堆栈发布…

c#开发-基础知识及有用技巧(一)

1、时间长度的计算 TimeSpan类。例如&#xff1a;TimeSpan span dateTime1 - dateTime2 方便啊2、从类&#xff08;Class)返回一个System.Type类型&#xff0c;用typeof关键字3、从一个对象实例(Object)返回一个System.Type类型&#xff0c;用GetType方法4、判断是否处于设计…

天呐!你知道MSBuild都干了些什么

一个典型的.NET5.0项目文件是这样的&#xff0c;看着非常简洁&#xff1a;<Project Sdk"Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>net5.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference I…

为什么理工类专业成绩好的人,英语总是很差?

▲ 点击查看在知乎上曾经有一个话题&#xff1a;为什么会有数学很好但英语很差的人&#xff1f;这个话题还被浏览了四十多万次。说起这个话题&#xff0c;评论中很多人也纷纷表示感同身受。在上学的时候&#xff0c;要么英语成绩好到飞起&#xff0c;要么数学成绩牛逼到不行。…

.Net Core with 微服务 - Polly 服务降级熔断

在我们实施微服务之后&#xff0c;服务间的调用变的异常频繁。多个服务之间可能是互相依赖的关系。某个服务出现故障或者是服务间的网络出现故障都会造成服务调用的失败&#xff0c;进而影响到某个业务服务处理失败。某一个服务调用失败轻则造成当前相关业务无法处理&#xff1…

IfElseActivity

IfElseActivity 1.IfElseActivity有两个IfElseBranch子控件&#xff0c;分别作为IfElse的两个分支容器,系统自动添加&#xff0c; 2.其中左边(为真件条)的IfElseBranch容器要设Condition 3.IfElse左边(为真件条)的IfElseBranch容器的Condition有两个条件模式:Code Condition,De…

荷兰人发明的新客机是劈叉的!乘客坐在机翼上

全世界只有3.14 % 的人关注了青少年数学之旅与汽车外型的复杂多变相比&#xff0c;飞机的外型似乎总是那么朴实无华&#xff0c;不管是客机还是战斗机&#xff0c;大约都是大家习以为常的那个样子……但是&#xff0c;终于有人要推陈出新了&#xff01;荷兰皇家航空公司与代尔夫…

预约 .NET Conf: Focus on F# 活动,赢得官方周边!

James: 最近 .NET 基金会预告了将在本月29日底举行的 .NET Conf: Focus on F# 线上活动&#xff0c;预约这次活动还能有机会赢得官方大礼包。.NET Conf: Focus on F# 是一个免费的、为期一天的直播活动&#xff0c;会上有来自社区和使用f#语言的微软团队的演讲者。学习 F# 如何…

.NET Day in China(上海-今日活动)| 线上线下

点击蓝字关注我们活动简介.NET 6 Preview 6 在 7月14日已经发布&#xff0c;.NET 6 是微软开启全平台统一一个 .NET 计划以来的第一个 LTS 版本&#xff0c;意义重大&#xff0c;微软在 .NET 6 引入了 MAUI&#xff0c;跨平台开发将更为简单&#xff0c;ASP.NET Core 也在不断的…

公司重金求数据分析师:为什么90%的公司都需要它?

全世界只有3.14 % 的人关注了青少年数学之旅混迹互联网的同学们&#xff0c;或多或少都对“数据分析师”这一职业有所耳闻。即使你不认识任何数据分析师&#xff0c;也一定看到过这类研究报告或者文章&#xff1a;Smart is the new sexy. 酷炫的图表&#xff0c;理性的分析阐述…

php配置问题汇总

前两天开始跟进PHP&#xff1b;我觉得&#xff0c;PHP的环境配置远比其他语言的要复杂很多。我所说的“其他语言”&#xff0c;包括Java&#xff0c;Oracle&#xff0c;scala&#xff0c;Python等。到现在PHP的环境被搭好&#xff0c;因为是全手动的配置&#xff0c;我完完整整…

Orchard Core 1.0.0 正式发布!

James: Orchard 最早是微软的员工创造的开源项目&#xff0c;使用的技术架构可以说是非常优秀&#xff0c;源码值得学习。功能也非常强大&#xff0c;支持模块化、多租户、工作流等等功能&#xff0c;可以说是 .NET 世界的 WordPress。一开始是.NET Framework 的&#xff0c;在…

[方法“Boolean Contains(System.Guid)”不支持转换为 SQL]的解决办法

Guid ClsID newGuid("d4ee9c52-8d68-4f33-9485-0926281c78ac");IList<Guid>Ids WebProduct.GetAllChildByID(ClsID);var query db.T_Products.Where(p >Ids.Contains((Guid)p.F_ClsID));//这一句编译时无错&#xff0c;但是一执行&#xff0c;就报错出错信息…