c# 4.0新特性一览

C# 的10 年

 

看着一个编程语言的诞生,然后逐步追随其成长,是一件相当有趣的事,特别是该编程语言一直都处于主流语言的时候,很可惜的,这种机会并不常有,C#是在我编程生涯中,唯一一个从其出生即跟随至今的编程语言。

 在C#诞生之初,也是Anders Hejlsberg离开Borland之后的数年后,对于一个老Delphi设计师而言,对于C#的感情因素远比其语言本质来得重,Anders是Delphi的主要掌舵者,他成功的将Delphi带入一个RAD工具前所未进过的殿堂,在他离开Borland而建立C#后,我们在C#上看到了Delphi的影子,PME的设计,Refection的进化,诸多设计都可见到Delphi的背影。当然,我并不是说C#是抄袭Delphi,毕竟当时也有人说C#与Java很像,C#与C++很像,这些其实都不重要,重要的是,C#是撷取了许多语言的优点而成的,对于程序设计师而言,这点就足够了。

 C# 1.0随着.NET Framework一起问市,创始者Anders将C# 1.0定位为Managed Version,这是继Java之后的一个中继平台高阶语言,与Java相同,.NET Framework中的CLR负责来执行由C# 编译器所产生的IL Code,借此将机器语言及中介语言切开,如你所见,优点是C#可以与VB.NET互通,在理论上,还能针对不同的CPU进行最佳化,这是传统直接编译成机器码的编译器所得不到的好处。

C# 2.0进入了泛型(Generic)时代,在这个版本中,程序设计师可以仅写一个Stack<T>,然后支持所有类型,而不用受object原型的拖累,泛型的优点在于其一开始就已定型,因此假设将一变量声明为Stack<int>,那么之后就不能够将string元素填入,既可脱开单一类型必须撰写对应支持的Stack负担,还得到了使用object所得不到的编译时期验证。

 C# 3.0开始,进入了一个极少数编程语言到过的境界,Anders大胆的于C#中加入了LINQ(Language Integrated Query),将查询语句硬是摆进了编程语言中,事实证明LINQ是个相当棒的发明。

 C# 4.0,一个崭新的时代,Anders再次显露了其大胆的个性,将原本受尽众人诟病的Un-Type Programming带入了C#,让原本以Typed Programming挂帅的C#,顿时多了另一个Dynamic Language的称号,虽然!人们对于Un-Type Programming的疑虑仍未解除,但Dynamic Language机制的加入,无疑的开启了C#另一条进步的路。

 10年,对于一个编程语言来说,并不是一段很长的时间,C#于这10年间的转变算是相当的快速,且每次的转变,都会让人觉得有疑虑,可是最后都会不禁对其大胆的尝试感到赞赏,当然!前提是你得是实务挂帅的人,因为只要从理论上及原则上来看,由C# 3.0开始,其轴心思想即不在旧有编程语言抱持的一贯原则上了,而是在如何加快设计师的生产力上。

 

严谨(Typed Programming) VS 松散(Dynamic Programming) 或者说 强类型(Typed Programming) VS 若类型(Dynamic Programming)

 

在C# 3.0之前,她是一个严谨的编程语言,也可称为是Typed Programming,意思是,当你将一个变数声明为int,那么你就不能把一个字串赋值给它,这样的做法有很多好处,其中之一就是编译器会于编译时期即告知设计者所犯下的类型错误,这大幅的减少了因类型错误而产生的BUG,同时间接的养成了C#设计师对于类型的敏感度。

从C# 3.0开始,因为LINQ的加入,var关键字出现了,其出现的原因是LINQ运算式的回传值,常常是设计师难以快速推估出来的,以下面的例子来说吧:

static void Main(string[] args)
{
            List<Person> list = new List<Person>() {
                new Person(){ID="001",Name="code6421",Age = 18},
                new Person(){ID="002",Name="tom",Age = 18},
                new Person(){ID="003",Name="mary",Age = 18}};
 
            List<Addresses> alist = new List<Addresses>()
            {
                new Addresses(){ID="001",Address="Taipen"},
                new Addresses(){ID="002",Address="Tainan"},
                new Addresses(){ID="003",Address="US"}
            };
 
            var result = from s1 in list
                    join s2 in alist on s1.ID equals s2.ID into p
                    select new { Name = s1.Name, Addresses = p };
            foreach (var item in result)
            {
                Console.WriteLine(item.Name);
                Console.WriteLine("-----------------");
                foreach (var addr in item.Addresses)
                    Console.WriteLine(addr.Address);
                Console.WriteLine("-----------------");
            }
            Console.ReadLine();
 }

  

如果没有var,那么就得写成下面这样:

 1 static void Main(string[] args)
 2 {
 3      List<Person> list = new List<Person>() {
 4         new Person(){ID="001",Name="code6421",Age = 18},
 5         new Person(){ID="002",Name="tom",Age = 18},
 6         new Person(){ID="003",Name="mary",Age = 18}};
 7  
 8      List<Addresses> alist = new List<Addresses>()
 9      {
10          new Addresses(){ID="001",Address="Taipen"},
11          new Addresses(){ID="002",Address="Tainan"},
12          new Addresses(){ID="003",Address="US"}
13      };
14  
15      IEnumerable<PersonJoinResult> result = from s1 in list
16               join s2 in alist on s1.ID equals s2.ID into p
17               select new PersonJoinResult{ Name = s1.Name, Addresses = p };
18      foreach (PersonJoinResult item in result)
19      {
20           Console.WriteLine(item.Name);
21           Console.WriteLine("-----------------");
22           foreach (Addresses addr in item.Addresses)
23                 Console.WriteLine(addr.Address);
24           Console.WriteLine("-----------------");
25      }
26      Console.ReadLine();
27    }
28 }
29  
30 public class PersonJoinResult
31 {
32     public string Name { get; set; }
33     public IEnumerable<Addresses> Addresses { get; set; }
34 }

很明显的,即使var背负上不定类型的臭名,但其对于代码的简化有着莫大的帮助,更何况,var于右赋值完成时,即转变为具体类型,因此精确的说,var还是具型(强类型)的设计。


C#于4.0中添加了一个新成员:dynamic,与var这种乍看不具型但实际具型的设计不同,dynamic是完全不具型的设计,它的类型是执行时期时决定的,所以下面的例子是可以通过编译的。

class Program
{
    static void Main(string[] args)
    {
      dynamic p = new Person();
      p.Hello();
    }
}
 
public class Person
{
    public string ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

Person并没有一个方法称为Hello,原本于Typed Programming的原则下,这个程序是无法通过编译的,但C# 4.0的dynamic型别却可以让这段程序通过编译,将一变量宣告为dynamic型别,即是告诉编译器【我知道我在做什么,你别管了!】。


有趣的还有下面这段代码。

static void Main(string[] args)
{
    dynamic p = 15;
    Console.WriteLine(p);
}

此时p的类型是什么呢?答案是object,事实上当你将某一变量宣告为dynamic时,C#编译器就会把它视为是object,然后以Lambda Expression的方式来处理你对此变量的调用、属性存取、Index存取等等,即使我们明确的知道p应该是Integer,但由于已经标为dynamic,自然的也就不能再经由具型来处理了。这个例子告诉我们,dynamic没那么聪明,不会因为你设了一个简单值给他,编译器便会很聪明的使用具型方式处理,一切还是循不具型方式来。因此,如非必要,否则别把原本可具型的东西宣告为dynamic,那对程式的效能及可读性是莫大的伤害。但也不必因此而不用它,毕竟利刃是给会用的人使用的。

var 與 dynamic (未完待续...)

 

转自 : http://h2appy.blog.51cto.com/609721/743662/

部分词语有替换,以便符合使用简体中文的人的习惯:

程序设计师

程式--编程

支援--支持

型别--类型

变数--变量

宣告--声明

世代--时代

函式呼叫--调用

 

posted @ 2017-04-11 14:40  银翼神驹  阅读(431)  评论(0编辑  收藏  举报