C#3.0中的新特性
转:http://baike.baidu.com/view/406857.htm
第一个特性:隐式类型化本地变量
class LocalVariables : AppRunner.AbstractApplication
{
public override void Run()
{
var intValue = 5;
var stringValue = "This is a string";
var customClass = new LocalVariables();
var intArray = new int[3] { 1, 2, 3 };
foreach (var value in intArray)
Console.WriteLine(value);
}
}
上面的代码将被解析成:
class LocalVariables : AppRunner.AbstractApplication
{
public override void Run()
{
int intValue = 5;
string stringValue = "This is a string";
LocalVariables customClass = new LocalVariables();
int[] intArray = new int[3];
foreach (int value in intArray)
Console.WriteLine(value);
}
}
要特别注意的是,由于变量的类型是通过变量初始值推断而来的,所以在声明变量的同时必需为变量指定初始值。并且,变量并不是没有类型的,变量一旦初始化之后,类型就确定下来了,以后就只能存储某种类型的值了,比如上面的stringValue的类型经推断为string,所以该变量就只能保存string类型的值了。
第二个特性:匿名类型
现在,C#3.0中的匿名类型特性就可以很好的解决上面提到的问题,通过匿名类型,我们可以简单使用new { 属性名1=值1, 属性名2=值2, ..... , 属性名n=值n }的形式直接在函数中创建新的类型,看下面这个例子:
class AnonymousType : AppRunner.AbstractApplication
{
public override void Run()
{
var anonymousType1 = new {
CardNumber = "10001", Name = "van’s", Sex = true
};
Console.WriteLine(anonymousType1.CardNumber);
Console.WriteLine
var anonymousType2 = new {
CardNumber = "10002", Name = "martin", Sex = true
};
anonymousType2 = anonymousType1;
}
}
在新类型中只能有字段成员,而且这些字段的类型也是通过初值的类型推断出来的。如果在声明新的匿名类型时,新类型的字段名、顺序以及初始值的类型是一致的,那么将会产生相同的匿名类型,所以上例中anonymousType1和anonymousType2的类型是相同的,自然能进行anonymousType2=anonymousType1的赋值。
第三个特性:隐式类型化数组
class AnonymousTypeArray : AppRunner.AbstractApplication
{
public override void Run()
{
var intArray = new[] { 1, 2, 3, 4, 5 };
var doubleArray = new[] { 3.14, 1.414 };
var anonymousTypeArray = new[] {
new { Name="van’s", Sex=false, Arg=22 },
new { Name="martin", Sex=true, Arg=23 }
};
Console.WriteLine(intArray);
Console.WriteLine(doubleArray);
Console.WriteLine(anonymousTypeArray[0].Name);
}
}
上面的代码中,anonymousTypeArray变量的声明同时运用了隐式类型化数组和匿名类型两种特性,首先创建匿名类型,然后再初始值列表,推断出数组的确切类型。
第四个特性:对象构造者
C#3.0中加入的对象构造者特性,使得对象的初始化工作变得格外简单,我们可以采用类似于数组初始化的方式来初始化类的对象,方法就是直接在创建类对象的表达式后面跟上类成员的初始化代码。具体示例如下:
class Point
{
public int X { get; set; }
public int Y { get; set; }
public override string ToString()
{
return "(" + X.ToString() + ", " + Y.ToString() + ")";
}
}
class Rectangle
{
public Point P1 { get; set; }
public Point P2 { get; set; }
public Rectangle()
{
P1 = new Point();
P2 = new Point();
}
public override string ToString()
{
return "P1: " + P1 + ", P2: " + P2;
}
}
class ObjectBuilder : AppRunner.AbstractApplication
{
public override void Run()
{
Point thePoint = new Point() { X = 1, Y = 2 };
Console.WriteLine("Point(X, Y) = ", thePoint);
Rectangle theRectangle = new Rectangle() {
P1 = { X = 1, Y = 1 }, P2 = { X = 100, Y = 200 }
};
Console.WriteLine(theRectangle);
}
}
我们在定义Point类的X和Y属性时,只须写上该属性的get和set访问器声明,C#编译器会自动为我们生成默认的get和set操作代码,当我们需要定义简单属性时,这个特性非常有用。
我们以new Point() { X = 1, Y = 2 }语句,轻松的完成了对Point类的初始化工作。在创建类的对象时,我们可以按照需要去初始化类的对象,只要在类的创建表达式后跟上要初始化属性的列表即可,且可以只对需要初始化的属性赋初值,而无需把所有属性的初始值都写上去。
在theRectangle对象的初始化表达式中,我们首先对P1属性进行初始化,然而P1属性也是一个自定义的类型,所以P1属性的初始化是另一个类型(Point)的初始化表达式,我们可以这样的方式来对更加复杂的类型进行初始化。
上篇文章中介绍了C# 3.0中比较简单的四个特性,分别是隐式类型化本地变量、匿名类型、隐式类型化数组,以及对象构造者,下面我将对C# 3.0中的较复杂,同时也是非常强大的几个特性进行介绍,供大家快速浏览。
第五个特性:集合构造者
C# 3.0中加入的集合构造者特性,可使我们享受到与普通数组一样的待遇,从而在创建集合对象的同时为其指定初始值。为了做到这一点,我们需要让我们的集合实现ICollection<T>接口,在这个接口中,完成初始化操作的关键在于Add函数,当我使用初始化语法为集合指定初始值时,C#编译器将自动调用ICollection<T>中的Add函数将初始列表中的所有元素加入到集合中,以完成集合的初始化操作。使用示例如下:
class CollectionInitializer : AppRunner.AbstractApplication
{
class StringCollection : ICollection<string>
{
public void Add(string item)
{
Console.WriteLine(item);
}
// Other ICollection<T> Members
}
public override void Run()
{
StringCollection strings = new StringCollection() { "Van's", "Brog", "Vicky" };
}
}
在这个示例中,编译器会自动为strings对象调用Add方法,以将初始值列表中的所有元素加入到集合中,这里我们只是简单将初始值列表中的元素输出到控制台。
第六个特性:Lambda表达式
C# 2.0中加入的匿名代理,简化了我们编写事件处理函数的工作,使我们不再需要单独声明一个函数来与事件绑定,只需要使用delegate关键字在线编写事件处理代码。
而C# 3.0则更进一步,通过Lambda表达式,我们可以一种更为简洁方式编写事件处理代码,新的Lambda事件处理代码看上去就像一个计算表达式,它使用"=>"符号来连接事件参数和事件处理代码。我可以这样写:SomeEvent += 事件参数 => 事件处理代码;下面是完整的示例:
delegate T AddDelegate<T>(T a, T b);
class LambdaExpression : AppRunner.AbstractApplication
{
public static event EventHandler MyEvent;
public override void Run()
{
MyEvent += delegate(object s, EventArgs e)
{
Console.WriteLine(s);
};
MyEvent += (s, e) => { Console.WriteLine(s); };
MyEvent(this, null);
AddDelegate<string> add = (a, b) => a + b;
Console.WriteLine(add("Lambda", "Expression"));
}
}
在上面的例子中,分别使用了匿名代理和Lambda表达式来实现同样的功能,可以明显看出Lambda表达式的实现更为简洁。我们在使用Lambda表达式编写事件处理代码时,无需指明事件参数的类型,且返回值就是最后一条语句的执行结果。
第七个特性:扩展方法
在对已有类进行扩展时,我们需将所有扩展方法都写在一个静态类中,这个静态类就相当于存放扩展方法的容器,所有的扩展方法都可以写在这里面。而且扩展方法采用一种全新的声明方式:public static 返回类型 扩展方法名(this 要扩展的类型 sourceObj [,扩展方法参数列表]),与普通方法声明方式不同,扩展方法的第一个参数以this关键字开始,后跟被扩展的类型名,然后才是真正的参数列表。下面是使用示例:
static class Extensions
{
public static int ToInt32(this string source)
{
return Int32.Parse(source);
}
public static T[] Slice<T>(this T[] source, int index, int count)
{
if (index < 0 || count < 0 || index + count > source.Length)
{
throw new ArgumentException();
}
T[] result = new T[count];
Array.Copy(source, index, result, 0, count);
return result;
}
}
class ExtensionMethods : AppRunner.AbstractApplication
{
public override void Run()
{
string number = "123";
Console.WriteLine(number.ToInt32());
int[] intArray = new int[] { 1, 2, 3 };
intArray = intArray.Slice(1, 2);
foreach (var i in intArray)
Console.WriteLine(i);
}
}
在上面的示例中,静态的Extensions类中有两个扩展方法,第一个方法是对string类的扩展,它为string类加入了名为ToInt32的方法,该方法没有参数,并返回一个int类型的值,它将完成数字字符向整数的转换。有了这个扩展方法之后,就可对任意string类的对象调用ToInt32方法了,该方法就像其本身定义的一样。
第二个扩展方法是一个范型方法,它是对所有数组类型的扩展,该方法完成数组的切片操作。
C# 3.0中的Linq表达式,就是大量运用扩展方法来实现数据查询的。
第八个特性:Linq查询表达式
C# 3.0中加入的最为复杂的特性就是Linq查询表达式了,这使我们可直接采用类似于SQL的语法对集合进行查询,这就使我们可以享受到关系数据查询的强大功能。
Linq查询表达式是建立在多种C# 3.0的新特性之上的,这也是我为什么最后才介绍Linq的原因。下面看一个例子:
class LinqExpression : AppRunner.AbstractApplication
{
public override void Run()
{
// 定义匿名数组persons, 并为其赋初值
var persons = new[] {
new { Name="Van's", Sex=false, Age=22 },
new { Name="Martin", Sex=true, Age=30 },
new { Name="Jerry", Sex=false, Age=24 },
new { Name="Brog", Sex=false, Age=25 },
new { Name="Vicky", Sex=true, Age=20 }
};
/*
执行简单Linq查询
检索所有年龄在24岁以内的人
查询结果放在results变量中
results变量的类型与数组persons相同
*/
var results = from p in persons
where p.Age <= 24
select p;
foreach (var person in results)
{
Console.WriteLine
Console.WriteLine();
// 定义匿名数组customers, 并为其赋初值
// 该数组是匿名类型的
var customers = new[] {
new {
Name="Van's", City="China", Orders=new[] {
new {
OrderNo=0,
OrderName="C# Programming Language(Second Edition)",
OrderDate=new DateTime(2007,9, 5)
},
new {
OrderNo=1,
OrderName="Head First Design Patterns(Chinese Edition)",
OrderDate=new DateTime(2007,9,15)
},
new {
OrderNo=2,
OrderName=Unleashed 2.0(Chinese Edition)",
OrderDate=new DateTime(2007,09,18)
},
new {
OrderNo=3,
OrderName="The C++ Programming Langauge(Special Edition)",
OrderDate=new DateTime(2002, 9, 20)
}
}
},
new {
Name="Brog", City="China", Orders=new[] {
new {
OrderNo=0,
OrderName="C# Programming Language(Second Edition)",
OrderDate=new DateTime(2007, 9, 15)
}
}
},
new {
Name="Vicky", City="London", Orders=new[] {
new { OrderNo=0,
OrderName="C++ Programming Language(Special Edition)",
OrderDate=new DateTime(2007, 9, 20)
}
}
}
};
/*
执行多重Linq查询
检索所在城市为中国, 且订单日期为2007年以后的所有记录
查询结果是一个匿名类型的数组
其中包含客户名, 订单号, 订单日期, 订单名四个字段
*/
var someCustomers = from c in customers
where c.City == "China"
from o in c.Orders
where o.OrderDate.Year >= 2007
select new o.OrderNo, o.OrderDate, o.OrderName };
foreach (var customer in someCustomers)
{
Console.WriteLine " + customer.OrderName + ", " +
customer.OrderDate.ToString("D")
);
}
}
}
从上面的例子中,我们可以看到Linq查询的强大特性,它允许我们进行简单查询,或者进行更为复杂的多重连接查询。且查询的结果还可以是自定义的匿名类型。
转载于:https://www.cnblogs.com/jackljf/archive/2012/11/14/3589000.html
C#3.0中的新特性相关推荐
- Entity Framework 4.3 中的新特性
原文地址:http://www.cnblogs.com/supercpp/archive/2012/02/20/2354751.html EF4.3于2月9号正式发布了,微软的EF小组最近一年开始发力 ...
- 第一次来,试发一帖!--ASP.NET 2.0 中的SqlCacheDependency特性
ASP.NET中的Page Cache是个很有用的东东,只要简单的在页面上方加上一个OutputCache标签,就可以让页面在制定的Duration内直接把自动保存在缓存中的页面内容输出,而不需要让A ...
- Spring 2.5:Spring MVC中的新特性
转载说明:infoQ就是牛人多,看人家去年就把Spring2.5注视驱动的MVC写出来了,还是这么详细,我真是自叹不如,今天偶尔看到这篇文章非常认真的拜读了2遍,简直是茅厕顿开啊....\(^o^)/ ...
- HALCON: HALCON 20.11.0.0 Progress主要新特性
HALCON: HALCON 20.11.0.0 Progress主要新特性 改进了基于形状的匹配 在HALCON 20.11中,对基于形状匹配的核心技术进行了改进,尤其是针对低对比度和高噪声的场景. ...
- ASP.NET 2.0 中的SqlCacheDependency特性
ASP.NET中的Page Cache是个很有用的东东,只要简单的在页面上方加上一个OutputCache标签,就可以让页面在制定的Duration内直接把自动保存在缓存中的页面内容输出,而不需要让A ...
- Spring Boot3.0正式发布及新特性解读
Spring Boot 3.0 正式发布 同时发布更新的还有 2.7.x 和 2.6.x 两条版本线,Spring Boot 是我见过的发版最守时的技术框架之一. Spring Boot 3.0 现已 ...
- .Net 6.0中的新增特性_.Net 6.0中的新增功能
.Net 6.0中的新增特性_.Net 6.0中的新增功能 一..Net 6 介绍 .NET 6 作为 LTS 长期支持版本,.NET 6 将会获得 3 年的技术支持. .NET 6 是首个原生支持 ...
- iOS7 中的新特性
iOS7 中的新特性 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳 ...
- 大数据哔哔集20210106 - Hadoop3.0有哪些新特性
[大数据哔哔集]是小编发起的每日大数据圈子最前沿.高频.有难度的面试题目以及资讯等. 精简版总结 1.JDK版本的最低依赖从1.7变成了1.82.HDFS支持Erasure Encoding3.Tim ...
最新文章
- SQL应用中级指南 Part4:(数据字典)
- 315MHz 高频射频发射模块
- 信号编程之sigaction函数和sigqueue函数
- [Day9]面向对象
- swift的可选值(optional)
- DellEMC品牌正式启用50%是上一代的R730对比R74
- 6. Qt 信号与信号槽(11)Qt::ConnectionType类型
- bioinformaitcs的latex版本参考文献填坑
- sol - 0x60,61,62
- 使用DBUnit做单元测试
- camera(21)---camera 客观测试 Imatest教程--曝光度测试
- mysql8.0登录不上去怎么回事_速看!智慧团建系统登录平台及信息查询入口
- VPX国产化千兆交换板
- kl距离 java_相对熵(relative entropy或 Kullback-Leibler divergence,KL距离)的java实现(三)...
- SecureCRT8.3.3软件包百度网盘
- CVE-2015-1427 ElasticSearch(Groovy 沙盒绕过 代码执行漏洞)
- 一片外文的计算机网络方面的文献,计算机网络专科外文文献 计算机网络专科核心期刊参考文献有哪些...
- 大学cad课要用计算机么,cad2010大学课程
- 拒绝低效的知识管理,从选择一款好的知识库工具开始
- 【OpenGL学习笔记⑤】——纹理变换【glm配置+两张图片交替渐变变换 + 纹理平移 + 实现雪花飘落】