C#.net

生活百科 2023-01-25 18:02生活百科www.aizhengw.cn

C#.net

C#是一个语言,.net是一个平台,上面支持用C#或者VB .Net写代码。

,C#不但可以开发基于.net的应用程式,也可以开发基于WinForm的程式,这就是区别。

. NET 是 Microsoft 的 XML Web 服务平台。不论作业系统或程式语言有何差别,XML Web 服务能使应用程式在 Internet 上传输和共享数据。

Microsoft® .NET 平台包含广泛的产品系列,它们都是基于 XML 和 Internet 行业标準构建,提供从开发、管理、使用到体验 XML Web 服务的每一方面。XML Web 服务将成为您今天正在使用的 Microsoft 的应用程式、工具和伺服器的一部分 — 并且将要打造出全新的产品以满足您所有业务需求。

更具体地说,Microsoft 正在五个方面创建 .NET 平台,即工具、伺服器、XML Web 服务、客户端和 .NET 体验。

若是单纯以概念来说,你可以把 .NET当做一个工作平台一般,它是一个开发环境的基底,提供了解其运作的相关机制那是有助于你利用它来开发。C#和 .NET主要是套用在网际网路。

基本介绍

  • 中文名C#.net
  • 外文名C#.net
  • 所属公司微软公司
  • 读做C-sharp

起源

C#(读做C-sharp)程式语言是由微软公司的Anders Hejlsberg和 Scott Willamette领导的开发小组专门为.NET平台设计的语言,它可以使程式设计师移植到.NET上。这种移植对于广大的程式设计师来说是比较容易的,因为C#从C,C++和Java发展而来,它採用了这三种语言最优秀的特点,并加入了它自己的特性。C#是事件驱动的,完全面向对象的可视化程式语言,我们可以使用集成开发环境来编写C#程式。使用IDE,程式设计师可以方便的建立,运行,测试和调试C#程式,这就将开发一个可用程式的时间减少到不用IDE开发时所用时间的一小部分。使用IDE迅速建立一个应用程式的过程称为快速反映开发。

C#2.0新特性

泛型

在我看来,泛型就是通过将数据类型参数化从而实现了代码的更为灵活的复用,泛型的出现使得C#能够使用同一段代码来操作多种数据类型。泛型无疑是C#2.0最重大的改进,它的出现赋予了C#代码更强的类型安全,更好的复用,更高的效率和更清晰的约束。

匿名方法

匿名方法允许我们将代码直接与委託实例相关联,使委託实例化工作更加直观和方便。在我看来,这只是C#又多了一种语法格式而已,不再像以前必须将方法名传给委託实例,而是又多了一种选择。

叠代器

叠代器允许我们更加方便的编写用于foreach语句的类型。在我看来,叠代器的出现只不过是改进了1.0中不便的可用foreach语句类型的编写限制,简化了一些接口。

局部类型

局部类型允许我们将一个类的代码分别写在不同的cs档案中。最典型的套用就是使用VS2005创建Form档案时,VS会自动将系统生成的代码与用户代码分开。局部类型通过partial关键字来声明。

空属类型

空属类型是一种像int,一样可以为空的变数类型。本质上是一种泛型的套用,是System .Nullable<>的一种类型实例化。

静态类

静态类是只用于包含静态成员的类型,它既不能实例化,亦不能被继承。

C#3.0新特性

1隐式类型化本地变数
这个特性非常简单,有些JavaScript的影子,我们可以统一使用使用"var"关键字来声明局部变数,而不再需要指明变数的确切类型了,变数的确切类型可通过声明变数时的初始值推断出来。这样一来,可以大大简化我们声明局部变数的工作量了,下面是一个例子
classLocalVariables:AppRunner.AbstractApplication{publicoverridevoidRun(){varintValue=5;varstringValue="Thisisastring";varcustomClass=newLocalVariables();varintArray=newint[3]{1,2,3};foreach(varvalueinintArray)Console.WriteLine(value);}}上面的代码将被解析成classLocalVariables:AppRunner.AbstractApplication{publicoverridevoidRun(){intintValue=5;stringstringValue="Thisisastring";LocalVariablescustomClass=newLocalVariables();int[]intArray=newint[3];foreach(intvalueinintArray)Console.WriteLine(value);}}
要特别注意的是,由于变数的类型是通过变数初始值推断而来的,所以在声明变数的必需为变数指定初始值。并且,变数并不是没有类型的,变数一旦初始化之后,类型就确定下来了,以后就只能存储某种类型的值了,比如上面的stringValue的类型经推断为string,所以该变数就只能保存string类型的值了。
2匿名类型
有些时候我们需要临时保存一些运算的中间结果,特别是当这些中间结果是由多个部份组成时,我们常常会去声明一个新的类型,以方便保存这些中间结果。表面上看起来这很正常,而细想之后就会发现,这个新类型只服务于这个函式,其它地方都不会再使用它了,就为这一个函式而去定义一个新的类型,确实有些麻烦。
C#3.0中的匿名类型特性就可以很好的解决上面提到的问题,通过匿名类型,我们可以简单使用new { 属性名1=值1, 属性名2=值2, ..... , 属性名n=值n }的形式直接在函式中创建新的类型,看下面这个例子
classAnonymousType:AppRunner.AbstractApplication{publicoverridevoidRun(){varanonymousType1=new{CardNumber="10001",Name="van’s",Sex=true};Console.WriteLine(anonymousType1.CardNumber);Console.WriteLinevaranonymousType2=new{CardNumber="10002",Name="martin",Sex=true};anonymousType2=anonymousType1;}}
在新类型中只能有栏位成员,而且这些栏位的类型也是通过初值的类型推断出来的。如果在声明新的匿名类型时,新类型的栏位名、顺序以及初始值的类型是一致的,那幺将会产生相同的匿名类型,所以上例中anonymousType1和anonymousType2的类型是相同的,自然能进行anonymousType2=anonymousType1的赋值。
3隐式类型化数组
这个特性是对隐式类型化本地变数的扩展,有了这个特性,将使我们创建数组的工作变得简单。我们可以直接使用"new[]"关键字来声明数组,后面跟上数组的初始值列表。在这里,我们并没有直接指定数组的类型,数组的类型是由初始化列表推断出来的。
classAnonymousTypeArray:AppRunner.AbstractApplication{publicoverridevoidRun(){varintArray=new[]{1,2,3,4,5};vardoubleArray=new[]{3.14,1.414};varanonymousTypeArray=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变数的声明运用了隐式类型化数组和匿名类型两种特性,创建匿名类型,然后再初始值列表,推断出数组的确切类型。
4对象构造者
我们在声明数组时,可以对其进行初始化,这样就省去了很多麻烦,在创建类的对象时,这招可就不灵了,我们要幺调用该类的构造函式完成对象的初始化,要幺就手工进行初始化。这两种方法都不太方便,使用构造函式来对对象进行初始化时,我们为了某种灵活性,可能需要编写构造函式的多个重载版本,实在是麻烦。
C#3.0中加入的对象构造者特性,使得对象的初始化工作变得格外简单,我们可以採用类似于数组初始化的方式来初始化类的对象,方法就是直接在创建类对象的表达式后面跟上类成员的初始化代码。具体示例如下
classPoint{publicintX{get;set;}publicintY{get;set;}publicoverridestringToString(){return"("+X.ToString()+","+Y.ToString()+")";}}classRectangle{publicPointP1{get;set;}publicPointP2{get;set;}publicRectangle(){P1=newPoint();P2=newPoint();}publicoverridestringToString(){return"P1:"+P1+",P2:"+P2;}}classObjectBuilder:AppRunner.AbstractApplication{publicoverridevoidRun(){PointthePoint=newPoint(){X=1,Y=2};Console.WriteLine("Point(X,Y)=",thePoint);RectangletheRectangle=newRectangle(){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中的较複杂,也是非常强大的几个特性进行介绍,供大家快速浏览。
5集合构造者
我们可以在声明数组的,为其指定初始值,方法是直接在数组声明的后面跟上初始值列表。这样就使数组的初始化工作变得简单,而对于我们自己创建的集合类型,就无法享受到与普通数组一样的待遇了,我们无法在创建自定义集合对象的,使用数组的初始化语法为其指定初始值。
C# 3.0中加入的集合构造者特性,可使我们享受到与普通数组一样的待遇,从而在创建集合对象的为其指定初始值。为了做到这一点,我们需要让我们的集合实现ICollection<T>接口,在这个接口中,完成初始化操作的关键在于Add函式,当我使用初始化语法为集合指定初始值时,C#编译器将自动调用ICollection<T>中的Add函式将初始列表中的所有元素加入到集合中,以完成集合的初始化操作。使用示例如下
classCollectionInitializer:AppRunner.AbstractApplication{classStringCollection:ICollection<string>{publicvoidAdd(stringitem){Console.WriteLine(item);}//OtherICollection<T>Members}publicoverridevoidRun(){StringCollectionstrings=newStringCollection(){"Van's","Brog","Vicky"};}}
在这个示例中,编译器会自动为strings对象调用Add方法,以将初始值列表中的所有元素加入到集合中,这里我们只是简单将初始值列表中的元素输出到控制台。
6Lambda表达式
C# 2.0中加入的匿名代理,简化了我们编写事件处理函式的工作,使我们不再需要单独声明一个函式来与事件绑定,只需要使用delegate关键字线上编写事件处理代码。
而C# 3.0则更进一步,通过Lambda表达式,我们可以一种更为简洁方式编写事件处理代码,新的Lambda事件处理代码看上去就像一个计算表达式,它使用"=>"符号来连线事件参数和事件处理代码。我可以这样写SomeEvent += 事件参数 => 事件处理代码;下面是完整的示例
delegateTAddDelegate<T>(Ta,Tb);classLambdaExpression:AppRunner.AbstractApplication{publicstaticeventEventHandlerMyEvent;publicoverridevoidRun(){MyEvent+=delegate(objects,EventArgse){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表达式编写事件处理代码时,无需指明事件参数的类型,且返回值就是一条语句的执行结果。
7扩展方法
当我们需要对已有类的功能进行扩展时,我们通常会想到继承,继承已有类,然后为其加入新的行为。而C# 3.0中加入的扩展方法特性,则提供了另一种实现功能扩展的方式,我们可以在不使用继承的前提下实现对已有类本身的扩展,这种方法并不会产生新的类型,而是採用向已有类中加入新方法的方式来完成功能扩展。
在对已有类进行扩展时,我们需将所有扩展方法都写在一个静态类中,这个静态类就相当于存放扩展方法的容器,所有的扩展方法都可以写在这里面。而且扩展方法採用一种全新的声明方式public static 返回类型 扩展方法名(this 要扩展的类型 sourceObj [,扩展方法参数列表]),与普通方法声明方式不同,扩展方法的第一个参数以this关键字开始,后跟被扩展的类型名,然后才是真正的参数列表。下面是使用示例
staticclassExtensions{publicstaticintToInt32(thisstringsource){returnInt32.Parse(source);}publicstaticT[]Slice<T>(thisT[]source,intindex,intcount){if(index<0||count<0||index+count>source.Length){thrownewArgumentException();}T[]result=newT[count];Array.Copy(source,index,result,0,count);returnresult;}}classExtensionMethods:AppRunner.AbstractApplication{publicoverridevoidRun(){stringnumber="123";Console.WriteLine(number.ToInt32());int[]intArray=newint[]{1,2,3};intArray=intArray.Slice(1,2);foreach(variinintArray)Console.WriteLine(i);}}
在上面的示例中,静态的Extensions类中有两个扩展方法,第一个方法是对string类的扩展,它为string类加入了名为ToInt32的方法,该方法没有参数,并返回一个int类型的值,它将完成数字字元向整数的转换。有了这个扩展方法之后,就可对任意string类的对象调用ToInt32方法了,该方法就像其本身定义的一样。
第二个扩展方法是一个范型方法,它是对所有数组类型的扩展,该方法完成数组的切片操作。
C# 3.0中的Linq表达式,就是大量运用扩展方法来实现数据查询的。
8Linq查询表达式
C# 3.0中加入的最为複杂的特性就是Linq查询表达式了,这使我们可直接採用类似于SQL的语法对集合进行查询,这就使我们可以享受到关係数据查询的强大功能。
Linq查询表达式是建立在多种C# 3.0的新特性之上的,这也是我为什幺才介绍Linq的原因。下面看一个例子
classLinqExpression:AppRunner.AbstractApplication{publicoverridevoidRun(){//定义匿名数组persons,并为其赋初值varpersons=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相同/varresults=frompinpersonswherep.Age<=24selectp;foreach(varpersoninresults){Console.WriteLineConsole.WriteLine();//定义匿名数组customers,并为其赋初值//该数组是匿名类型的varcustomers=new[]{new{Name="Van's",City="China",Orders=new[]{new{OrderNo=0,OrderName="C#ProgrammingLanguage(SecondEdition)",OrderDate=newDateTime(2007,9,5)},new{OrderNo=1,OrderName="HeadFirstDesignPatterns(ChineseEdition)",OrderDate=newDateTime(2007,9,15)},new{OrderNo=2,OrderName=Unleashed2.0(ChineseEdition)",OrderDate=newDateTime(2007,09,18)},new{OrderNo=3,OrderName="TheC++ProgrammingLangauge(SpecialEdition)",OrderDate=newDateTime(2002,9,20)}}},new{Name="Brog",City="China",Orders=new[]{new{OrderNo=0,OrderName="C#ProgrammingLanguage(SecondEdition)",OrderDate=newDateTime(2007,9,15)}}},new{Name="Vicky",City="London",Orders=new[]{new{OrderNo=0,OrderName="C++ProgrammingLanguage(SpecialEdition)",OrderDate=newDateTime(2007,9,20)}}}};/
执行多重Linq查询
检索所在城市为中国, 且订单日期为2007年以后的所有记录
查询结果是一个匿名类型的数组
其中包含客户名, 订单号, 订单日期, 订单名四个栏位
/varsomeCustomers=fromcincustomerswherec.City=="China"fromoinc.Orderswhereo.OrderDate.Year>=2007selectnew{o.OrderNo,o.OrderDate,o.OrderName};foreach(varcustomerinsomeCustomers){Console.WriteLine(customer.OrderName+","+customer.OrderDate.ToString("D"));}}}
从上面的例子中,我们可以看到Linq查询的强大特性,它允许我们进行简单查询,或者进行更为複杂的多重连线查询。且查询的结果还可以是自定义的匿名类型。

控制项

C#提供了很多控制项用于开发应用程式。
C#标準控制项根据其套用环境分为两类
Windows Form控制项主要用于Windows应用程式的开发。所有的Windows控制项都是从Control类中派生来的,该类包含了所有用户界面的Windows Form组件,其中也包括Form类。Control类中包括了很多位所有控制项所共享的属性、事件和方法。它包含複选框、文本框、按钮、标籤、图像列表等。
Web窗体控制项主要用于Web应用程式的开发。它是专门针对Asp .NET Web窗体设计的伺服器控制项。Web窗体控制项包含在命名空间System.Web.UI.WebControls中,当用户使用Visual Studio创建Web窗体页面时,会自动在后台代码档案中添加引用该命名空间的Using语句。
.NET Compact Framework 提供了可以满足大多数设备项目需要的Windows Form控制项。若要使用这些控制项没有的功能,可以从公共控制项派生您自己的自定义控制项。可以通过定义从 Control 类或从程式集中的现有 UserControl 继承的公共类型创建自定义控制项。
最简单的控制项自定义是重写公共控制项的方法。例如,可以重写 TextBox 控制项的 OnKeyPress 继承方法,提供将输入限制为数字字元的代码。
如若觉得自定义控制项过于浪费时间和複杂,也可以从受信任的来源下载控制项,并通过添加引用来导入自定义控制项。支持这些自定义的.NET的控制项有ComponentOne Studio, Spread,ActiveReports、MultiRow等。
上一篇:Pop Evil 下一篇:OPPO ulike U701

Copyright@2015-2025 www.aizhengw.cn 癌症网版板所有