随着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#区的所有版主都至少写一篇 :)
现在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#区的所有版主都至少写一篇 :)
不过partial class符合C++程序员类分开实现的准则,不错。
呵呵,可为空的值类型。
把原先程序的部分代码用泛型进行了重构实现,给自己定的原则就是尽量通过泛型来实现强类型,减少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
improved productivity.
http://msdn2.microsoft.com/en-us/library/zycewsya.aspx实际上就是堆栈中的数组unsafe struct Point3D
{
public fixed int Coordinates[3];
}Console.WriteLine(sizeof(Point3D)); // 12
public void test()
{
TheEvent testdel1 = new TheEvent(del1);
testdel1(12);
}public void del1(int x)
{
Console.WriteLine("output x : {0}", x);
}
and now I want to study aop
{
public static void AddPrameters( CommandType command, ParameterType[] parameters )
{
//...
}
}我的DbCommandHelper要实现什么接口?
再说List<>和Dictionary<>什么接口都不实现照样也能很好的运转。
12月16号去看看再说。好像.net2.0里,还有个vsts是重点。谁给解释一下啊。是不是就是 vss.net?
--------------------------------------------------------------------------------不是
C# 泛型,简直是鸡肋, 又不是静态编译! 更搞笑的是,所有的泛型类型都要继承一个接口!
--------------------------------------------------------------------------------个人觉得此说法偏颇。
其实语言的改进主要是为了在编译器允许的情况下切合人的思考方式并减少工作量。
我在实际项目中用过的C#2.0语言扩展主要是匿名方法,泛型,不完全类型,和改进的迭代器:
以前所有的事件响应都是分成两部分,先定义一个委托然后绑定到事件处理函数。我们经常看到类似下面的代码:
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("您点击了一个按钮");};
匿名方法还可以捕获或引用其它方法的参数、局部变量、属性等,代码量明显减少,套句广告词就是“简单方便又实惠”。
以前通用的数据结构只能用object类型来存贮各种类型的数据。在C#2.0里通过某个类型建立的Stack<T>的实例,可以接受各种类型的数据,类型参数T就像个占位符,直到使用时才指定一个实际的类型。
关于泛型大家可以参见速马在上海.Net俱乐部活动上讲泛型用过的ppt,明了易懂。个人觉得泛型是C#2.0带给我们最重要的语言扩展。
http://www.sunmast.com/speech/050813/GenericStudy.zip
不完全类型可以使一个类在类型修饰符partial修饰下在不同部分实现。如:
我们以前实现类时用的
public class Class1
{
...........(这是一段语句)
,,,,,,,,,,,(另一段语句)
}
在C#2.0里我们可以通过 public partial class Class1
{
...........
} public partial class Class1
{
,,,,,,,,,,,
}
来实现,甚至这几个部分可以在不同的源文件中。要注意的是不完全类型的所有部分要一块儿编译,同时,不完全类型不允许对已经被编译的类型进行扩展。团队开发的时候,不完全类型很有用。
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();
}
}
这样就既能保证遍历集合时的类型转换是安全无误的,同时又能避免冗余转换,使效率提高。
"同时,不完全类型不允许对已经被编译的类型进行扩展"
这个能详细解释一下么?
"同时,不完全类型不允许对已经被编译的类型进行扩展"
这个能详细解释一下么?
----------------------------------------------------------------------------
我的意思是说不完全类型(也有人翻译成不完整类型或局部类型)在使用中要注意:一个类型的所有部分必须被同时编译,不能先编译一个类型的某些部分,然后再编译一个类型的其他部分。
中文版:
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中文版的全部便子都是错的,晕死。看来真的要学习一下那些 英语 才可以了。
严重关注ing.......
学习中...
int add(<t> para)
{
return (int)para; // 范型数据无法进行类型转换,此处会出现编译错误
}
编译都通不过
再说看起来就是把个object换成了T。泛型的意义在有两个T的时候才会很好的体现。
泛型在值类型上的确不错,对引用对象来说几乎没有性能上的改变.
泛型的转换也很麻烦,只能向接口和object,不能直接转换成其他类型.
List<int> list=new List<int>();
IList list = (IList)new List<int>();
两者在遍历操作效率差别太多有点失望.
泛型的其他好处暂时没有休会到,继续努力学习中
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的时候才能体现出他的魅力。
{
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 );
没泛型并不会难看得多
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做遍历操作就失去了原有的效率.
对一些运行期才确定类型的操作,泛型感觉并不好用;如果泛型只有以上功能真的有点失望.
再从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 );
修改为:
IComparable[] inputarr = (IComparable[]) list.ToArray( typeof( IComparable ) );
int[] l2 = new int[]{1,2,3,4,5}
两者在操作效率差除了拆箱,还能有什么?
我并没有说泛型没有,只是我所理解的没有让我感到惊喜.
而我的观点是,.NET的范型,除了能用编译器更好的进行类型检查之外,别的地方用处不大。
并且,性能提升并不明显,装箱/拆箱的过程,不要和类型转换相混淆。以装箱为例:
int i = 5;
object o = i;
这里实际上做了两步操作,一个是把数据从线程堆栈复制到GC堆上,另一步是类型转换范型只能避免第二步,得到一点点性能提升;而最影响效率的地方却是第一步:把数据从线程堆栈复制到GC堆上。C#的范型也远不如C++模板那样灵活,要做“模板元编程”之类的高级用法,在C#根本就不可能。各位有兴趣的话可以比较一下C#和C++在这方面的差别。PS.我这段大概要让人失望了,但这是事实,C#范型被讨论的实在太多了,而实际上它的用处不大。其好处主要在编译时更好的类型检查,减少人为错误的可能性。