随着Visual Studio 2005的发布,我们.NET开发者又迎来了新的挑战。而对于C#,其语法、语义,和编译器都进行了一个升级。从表面上看,新的语法都很简单,新的编译器行为也不难掌握,但新引入语言的东西,往往能对一门语言产生更深远的影响。令我映像深刻的是C++模板的概念,也许其创始人也没有想到基于模板的编程居然可以有现在这么多技巧,比如C++模板元编程(Template Meta-Programming),利用编译期的就计算可以做到那么多神奇的事情。
现在C#有了Generics — .NET里最接近模板的概念(虽然为了强类型特性牺牲了很多功能),你能利用这个特性做出什么样的巧妙的应用呢?C# 2.0还引入了Anonymous Methods,C#似乎又具有了一定的动态语言的特性。而相对于Ruby、 Python这样原生的动态语言,C# 2.0又能从动态特性(如果有的话)得到多少好处?以上两点和C#强类型语言的要求实际上是有冲突的,如今C# 2.0依然是个完全的强类型的语言,那么在C# 2.0里面它们的应用会受到什么样的限制?其他很多新特性,比如partial class,iterative return(yield return),c-style array,等等,会给我们编写程序的过程带来什么好处呢?此帖意在抛砖引玉,欢迎大家在这里写下自己的体会,比如新的语言怎样做到了以前做不到的事情,它如何提高了开发效率,或者是如何提高了运行效率,以及它引入了什么样的思想,等等。要是弄不清楚如何发挥新语言的优势,那如同用ASP的方式写ASP.NET、用C的思路写C++一样,是一种浪费。希望C#区的所有版主都至少写一篇 :)

解决方案 »

  1.   

    btw, C#区要增加一名版主,这里是展现你的才华的好机会 :-)
      

  2.   

    其他新特性还没有用到。
    不过partial class符合C++程序员类分开实现的准则,不错。
      

  3.   

    为什么感觉很好还正在酝酿啊……另外似乎忽略了一个特性:int id = (int?) command.ExecuteScaler() ?? -1;
    呵呵,可为空的值类型。
      

  4.   

    刚接触C# 2.0的时候,最先使用的是泛型,包括泛型类、泛型结构、泛型接口及泛型方法。
    把原先程序的部分代码用泛型进行了重构实现,给自己定的原则就是尽量通过泛型来实现强类型,减少box和unbox。同时泛型提供的约束功能,增强的类型反射机制,感觉很好用,编写程序更加灵活了。当然匿名方法、可空类型、新的迭代器等新语言特性也将会有重要的应用。
    msdn上的一些文章也讲到很多,
    C# 2.0:使用匿名方法、迭代程序和局部类来创建优雅的代码
    http://www.microsoft.com/china/msdn/library/langtool/vcsharp/CreElegCodAnymMeth.mspx
    C# 泛型简介
    http://www.microsoft.com/china/msdn/library/langtool/vcsharp/csharpgenerics.mspx
      

  5.   

    没有用过C++。过去是用VB的,觉得C#比VB好多了。^_^
      

  6.   

    .NET 2.0 类库同时也封装了很多以前没有好东东比如以前你想让窗口拥有一个像Office那样漂亮的菜单和工具栏的话,只有自己去重写OnPaint事件2.0直接提供了MenuStrip、ToolbarStrip等控件,直接就是Office风格的,功能十分强大2.0下写winform程序直接就可以支持XP Visual Style,不像以前还要手动添加一个.manifest文件我用vs2005有一段时间了,感觉好处还有很多很多,等着大家自己去体验吧
      

  7.   

    使用最多的是Generic,前不久刚完成一个使用2.0beta2开发的网站。www.goldweb.com.cn
      

  8.   

    2.0+VS2005+TeamSystem也许真的带来了质的飞跃
      

  9.   

    我现在在公司的机器是celeron 2.4, 256MB的,如果装vs.net怕会多慢阿。
      

  10.   

    less code,
    improved productivity.
      

  11.   

    我还没用,因为大部分虚机服务商的.net框架还是1.1,.NET2.0可以完全兼容.NET1.1吗??
      

  12.   

    弱弱地问: c-style array具体何解?
      

  13.   

    >>> 弱弱地问: c-style array具体何解
    http://msdn2.microsoft.com/en-us/library/zycewsya.aspx实际上就是堆栈中的数组unsafe struct Point3D
    {
        public fixed int Coordinates[3];
    }Console.WriteLine(sizeof(Point3D)); // 12
      

  14.   

    delegate经常被人用来与回调相比较,其实两者在某种程度上由很多共同点。不过delegate有很多更加强大的地方。   首先,delegate中可以注册任意多个回调,在一个delegate被调用的时候,已经注册的过程将会被逐个调用。  其次,delegate允许注册一个对象的方法,而不像C++中指可以使用静态方法或者全局方法作为函数指针,提供了更多的灵活性,同时也暗示我们,delegate中按照某种方式保存了object的很多信息。  在C#2.0的匿名delegate中,我们甚至可以访问当前匿名委托的上下文变量。接下来的文章中我们将会通过实际的例子,来看看强大的delegate。  首先,让我们看看在C#1.2中的一个典型的委托的写法。
      

  15.   

    public delegate void TheEvent(int a); 
    public void test()
    {
     TheEvent testdel1 = new TheEvent(del1);
     testdel1(12);
    }public void del1(int x)
    {
     Console.WriteLine("output x : {0}", x);
    }
      

  16.   

    感觉有很多方便之处,不管是做Web或是Win开发,她都提供了强大的控件库,而且在处理常用的业务上也都较1.1有很大的提高
      

  17.   

    12月16号去看看再说。好像.net2.0里,还有个vsts是重点。谁给解释一下啊。是不是就是 vss.net?
      

  18.   

    yes, I think .net 2.0 is powerful,For example, asp.net, now in vs2005 we can change the ui by skin, we need not develop so many css.
    and now I want to study aop
      

  19.   

    范型更多的意义是强类型检查。另外继承接口纯粹是无稽之谈。List<T>和Dictionary<TKey,TValue>中的T、TKey和TValue就不需要实现任何接口。而如我这样写个帮助类:  public class DbCommandHelper< CommandType, ParameterType > where CommandType : IDbCommand where ParameterType : IDataParameter
      {
        public static void AddPrameters( CommandType command, ParameterType[] parameters )
        {
          //...
        }
      
      }我的DbCommandHelper要实现什么接口?
    再说List<>和Dictionary<>什么接口都不实现照样也能很好的运转。
      

  20.   

    发现C#/Java啥的现在越来越像C++了,不知道啥时候终于忍不住把指针又给弄进来了,呵呵
      

  21.   

    回复人: wuyazhe(我的宝贝叫阿刺) ( ) 信誉:100  2005-12-08 08:49:00  得分: 0   
       12月16号去看看再说。好像.net2.0里,还有个vsts是重点。谁给解释一下啊。是不是就是 vss.net?
    --------------------------------------------------------------------------------不是
      

  22.   

    回复人: weisunding(鼎鼎) ( ) 信誉:100  2005-12-08 09:20:00  得分: 0   
     
       C# 泛型,简直是鸡肋, 又不是静态编译! 更搞笑的是,所有的泛型类型都要继承一个接口!
    --------------------------------------------------------------------------------个人觉得此说法偏颇。
      

  23.   

    觉得现在CSDN很多回帖质量不高。响应楼主号召,说说C#2.0带给我的新东西。
    其实语言的改进主要是为了在编译器允许的情况下切合人的思考方式并减少工作量。
    我在实际项目中用过的C#2.0语言扩展主要是匿名方法,泛型,不完全类型,和改进的迭代器:
      

  24.   

    1、关于匿名方法:
    以前所有的事件响应都是分成两部分,先定义一个委托然后绑定到事件处理函数。我们经常看到类似下面的代码:
    this.button1.Click += new System.EventHandler(this.button1_Click);
                    ................
                    ................
    private void button1_Click(object sender, System.EventArgs e)
    {
    MessageBox.Show("您点击了一个按钮");
    }
    在C#2.0中,可以直接在原来定义委托的地方直接编写以一个delegate关键字开头的匿名方法,用如下代码即可实现同样功能:
                    button1.Click+=delegate{MessageBox.Show("您点击了一个按钮");};
    如果这个匿名方法的委托类型编译器认不出来,可以用强制类型转换,如:
                    Delegate delebutton1click=(EventHandler)delegate{MessageBox.Show("您点击了一个按钮");};
    匿名方法还可以捕获或引用其它方法的参数、局部变量、属性等,代码量明显减少,套句广告词就是“简单方便又实惠”。
      

  25.   

    2.泛型:
    以前通用的数据结构只能用object类型来存贮各种类型的数据。在C#2.0里通过某个类型建立的Stack<T>的实例,可以接受各种类型的数据,类型参数T就像个占位符,直到使用时才指定一个实际的类型。
    关于泛型大家可以参见速马在上海.Net俱乐部活动上讲泛型用过的ppt,明了易懂。个人觉得泛型是C#2.0带给我们最重要的语言扩展。
    http://www.sunmast.com/speech/050813/GenericStudy.zip
      

  26.   

    3.不完全类型(有的人翻译成不完整类型):
    不完全类型可以使一个类在类型修饰符partial修饰下在不同部分实现。如:
    我们以前实现类时用的
                    public class Class1
                    {
                     ...........(这是一段语句)
                     ,,,,,,,,,,,(另一段语句)                        
                    }
    在C#2.0里我们可以通过 public partial class Class1
    {
    ...........
    } public partial class Class1
    {
    ,,,,,,,,,,,
    }
    来实现,甚至这几个部分可以在不同的源文件中。要注意的是不完全类型的所有部分要一块儿编译,同时,不完全类型不允许对已经被编译的类型进行扩展。团队开发的时候,不完全类型很有用。
      

  27.   

    4.迭代器
    C#的foreach语句是VB那里学来的,被用于迭代一个可枚举集合的所有元素。为了可以被枚举,集合必须具有一个无参数GetEnumerator()方法,它返回一个枚举器。一般情况下,枚举器实现麻烦。在C#1.x里对于值类型集合在foreach时,每个值都经历装箱和拆箱操作,引用类型集合在foreach时也有个多余的castclass指令来保证枚举出来的值进行类型转换时不发生错误。但这个问题在C#2.0中使用迭代器就方便多了。比如原来C#1.x中的下列语句
    using System.Collections;
    public class Tokens : IEnumerable
    {
         ...
      Tokens f = new Tokens(...);
      foreach (string item in f)
      {
         Console.WriteLine(item);
      }
      ...
    }
    C#2.0中提供了强类型的泛型IEnumerable定义,所以可以写成
    namespace System.Collections.Generic
    {
      public interface IEnumerable<ItemType>
      {
         IEnumerator<ItemType> GetEnumerator();
      }
      public interface IEnumerator<ItemType> : IDisposable
      {
         ItemType Current{get;}
         bool MoveNext();
      }
    }
    这样就既能保证遍历集合时的类型转换是安全无误的,同时又能避免冗余转换,使效率提高。
      

  28.   

    5.C#2.0还有其它的一些新特性,如新增了static class,我的理解就相当于以前有人想定义的abstract sealed class,只不过规定好static这个关键字不会引起歧义。等等。
      

  29.   

    partial class的介绍里面
    "同时,不完全类型不允许对已经被编译的类型进行扩展"
    这个能详细解释一下么?
      

  30.   

    回复人: slimsymphony(我们在前世约定,一起穿行这世界) ( ) 
    "同时,不完全类型不允许对已经被编译的类型进行扩展"
    这个能详细解释一下么?
    ----------------------------------------------------------------------------
    我的意思是说不完全类型(也有人翻译成不完整类型或局部类型)在使用中要注意:一个类型的所有部分必须被同时编译,不能先编译一个类型的某些部分,然后再编译一个类型的其他部分。
      

  31.   

    关于C#2.0语言本身,大家还可以参见C#2.0语言规范。除此之外,祝成的李建忠老师在msdn webcast上有一个“C#2.0锐利体验”的系列讲座,大家可以去收听。在我听过的webcast中,李建忠是各方面都比较优秀的一个讲师。
      

  32.   

    我上面提到的都是在实际项目里已经多次用到的,C#2.0还有其他新颖之处,包括空属类型、名称空间别名限定符、定长buffer、Pragma指示符、Conditional特性类等,目前基本没用到。另外常用的一个新特性就是属性访问器保护级别的变化,估计大家都知道了。
      

  33.   

    以上都是些最简单的介绍,还有很多如匿名方法可以来模拟closure,yield甚至可以模拟状态机,而泛型更大大提高了代码的复用性等都没有提及。不过有一点需要特别说明的是:我觉得语言本身并不是特别重要,最重要的东西在语言之外。
      

  34.   

    感觉范型带来的好处有限,倒是那个 int? i 变量比较有用
      

  35.   

    今天到msdn看了一下C#的泛型。
    中文版:
    http://www.microsoft.com/china/msdn/library/langtool/vcsharp/csharpgenerics.mspx
    英文版:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/csharp_generics.asp中文版的全部便子都是错的,晕死。看来真的要学习一下那些 英语 才可以了。
      

  36.   

    1.0才刚开始学,2.0又出来了!
    严重关注ing.......
      

  37.   

    我在jdk 5.0的环境下使用了generic,还是不错的特性,回头在c#下也看看,应该是好东西,把错误留在compile-time是个好选择!
      

  38.   

    C# 3.0 与未来发展C# 2.0 的核心机制在于泛行编程的引入,它赋予了类型参数式多态的能力,将对今后的C#代码构造有重要影响。研发中的C# 3.0 将XML、SQL两中数据处理技术引入到C#这样的强类型语言中,极大地丰富了C#语言的数据处理能力,是一个极具远见的创新。C#语言的发展越来越多体现融合“设计模式+库”的思想,“语言的发展就是库的发展”。
    学习中...
      

  39.   

    C#范型好像也就一般,只能用于集合,不能用于计算
    int add(<t> para)
    {
        return (int)para;  // 范型数据无法进行类型转换,此处会出现编译错误
    }
      

  40.   

    愣没看明白楼上的代码
    编译都通不过
    再说看起来就是把个object换成了T。泛型的意义在有两个T的时候才会很好的体现。
      

  41.   

    Ivony():说的就是不支持类型装换,看注释!!
      

  42.   

    终于把事务完全分离出来,这个我是挺喜欢的.
    泛型在值类型上的确不错,对引用对象来说几乎没有性能上的改变.
    泛型的转换也很麻烦,只能向接口和object,不能直接转换成其他类型.
    List<int> list=new List<int>();
    IList list = (IList)new List<int>();
    两者在遍历操作效率差别太多有点失望.
    泛型的其他好处暂时没有休会到,继续努力学习中
      

  43.   

    Ivony():说的就是不支持类型装换,看注释!!====================================================================泛型就不是这么用的,泛型其中一个作用就是为了避免强制类型转换这种运行时错误,泛型本来就是强类型的,你要去转换类型干吗?只能说是思路错误。泛型对于容器的重要性,我记得以前有一个笑话。这是一个装苹果的容器:
    AppleCollection : IList
    然后,我们往里面添加苹果:
    appleCollection.Add( apple );
    这是没问题的。
    可是,如果我们往里面扔个毒药进去呢?
    appleCollection.Add( poison );
    对,你会说这扔不进去,因为AppleCollection.Add所接受的参数是Apple型的。可是,如果是这样:
    ((IList) appleCollection).Add( poison );
    当然了,你可以抛出一个异常:
    IList.Add( object obj )
    {
      Apple apple = obj as Apple;
      if ( apple == null )
        throw new NotSupportException();
      //...
    }看看这段代码,一个强类型的Add,一个显示实现接口的Add,还有这么多莫名其妙的代码。泛型不光是省略这些代码的语法。刚才我在上面说过,泛型要在有两个T的时候才能体现出他的魅力。
      

  44.   

    看看泛型是怎样优雅的:  public T[] Sort<T>( T[] items ) where T : IComparable<T>
      {
        List<T> list = new List<T>();    foreach ( T item in items )
        {
          bool flag = true;
          for ( int i = 0; i < list.Count; i++ )
          {
            if ( item.CompareTo( list[i] ) < 0 )
            {
              list.Insert( i, item );
              flag = false;
              break;
            }
          }
          if ( flag )
            list.Add( item );
        }
        return list.ToArray();
      }测试代码:
        int[] arr = new int[] { 10, 3, 2, 5, 7, 2, 8, 4 };    int[] arr1 = Sort( arr );
      

  45.   

    说真的并不觉得优雅
    没泛型并不会难看得多
    public system.IList Sort( IComparable[] items ) 
       IList list = new ArrayList();    foreach ( IComparable item in items )
        {
          bool flag = true;
          for ( int i = 0; i < list.Count; i++ )
          {
            if ( item.CompareTo( list[i] ) < 0 )
            {
              list.Insert( i, item );
              flag = false;
              break;
            }
          }
          if ( flag )
            list.Add( item );
        }
        return list.ToArray();
      }
    在这个例子上使用范型的确有它的好处,因为这里处理的值类型.
    除了值类型效率上有提高,泛型对开发人员来说有约束规则可以说是一件好事情.
    IComparable[]可以是不同类型的IComparable实现,通过泛型约束就严紧多了.
     List<int> list = new List<int>();
    把list转成IList做遍历操作就失去了原有的效率.
    对一些运行期才确定类型的操作,泛型感觉并不好用;如果泛型只有以上功能真的有点失望.
      

  46.   

    楼上的,你好像简化了程序,我输入输出的可都是数组。从int[]->IComparable[]就不是一件容易的事情,需要一个遍历拷贝。
    再从ArrayList->int[]也需要一个强类型转换。最大的问题是,这些不能在你的函数里面处理,因为你要做通用的,你不能知道他到底是什么类型的。
    我来帮你的函数写个范例:
    int[] arr = new int[] { 10, 3, 2, 5, 7, 2, 8, 4 };ArrayList list = new ArrayList()
    foreach( int i in arr )
      list.Add( i );IComparable[] inputarr = list.ToArray( typeof( IComparable ) );ArrayList output = (ArrayList) Sort( inputarr );
    int[] arr1 = (int[]) output.ToArray( typeof( int ) );
    效率差别岂止是装箱拆箱??!
        int[] arr = new int[] { 10, 3, 2, 5, 7, 2, 8, 4 };    int[] arr1 = Sort( arr );
      

  47.   

    IComparable[] inputarr = list.ToArray( typeof( IComparable ) );
    修改为:
    IComparable[] inputarr = (IComparable[]) list.ToArray( typeof( IComparable ) );
      

  48.   

    IList l1 = new int[]{1,2,3,4,5}
    int[] l2 = new int[]{1,2,3,4,5}
    两者在操作效率差除了拆箱,还能有什么?
    我并没有说泛型没有,只是我所理解的没有让我感到惊喜.
      

  49.   

    你要把代码看全,泛型更重要的是约束,如果你不是转换为IComparable[],那么你就不得不一个个的is IComparable并抛出异常。泛型把一些运行时的错误转换到了编译时,提供了更多的抽象。尽管C#里面的泛型没有C++的模版功能强大,但是它的确可以创造出更优雅的代码。你执著于拆箱上,有没有想过那些偶尔抛出的异常,亢余重复的代码,强类型的转换,五花八门的变量都是效率的下降呢?
      

  50.   

    终于看到几个有点深度的讨论了 :)我同时支持henryfan1和Ivony
    而我的观点是,.NET的范型,除了能用编译器更好的进行类型检查之外,别的地方用处不大。
    并且,性能提升并不明显,装箱/拆箱的过程,不要和类型转换相混淆。以装箱为例:
    int i = 5;
    object o = i;
    这里实际上做了两步操作,一个是把数据从线程堆栈复制到GC堆上,另一步是类型转换范型只能避免第二步,得到一点点性能提升;而最影响效率的地方却是第一步:把数据从线程堆栈复制到GC堆上。C#的范型也远不如C++模板那样灵活,要做“模板元编程”之类的高级用法,在C#根本就不可能。各位有兴趣的话可以比较一下C#和C++在这方面的差别。PS.我这段大概要让人失望了,但这是事实,C#范型被讨论的实在太多了,而实际上它的用处不大。其好处主要在编译时更好的类型检查,减少人为错误的可能性。