複製鏈接
請複製以下鏈接發送給好友

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#.net起源

C#(讀做C-sharp)編程語言是由微軟公司的Anders Hejlsberg和 Scott Willamette領導的開發小組專門為.NET平台設計的語言,它可以使程序員移植到.NET上。這種移植對於廣大的程序員來説是比較容易的,因為C#從CC++Java發展而來,它採用了這三種語言最優秀的特點,並加入了它自己的特性。C#是事件驅動的,完全面向對象可視化編程語言,我們可以使用集成開發環境來編寫C#程序。使用IDE,程序員可以方便的建立,運行,測試和調試C#程序,這就將開發一個可用程序的時間減少到不用IDE開發時所用時間的一小部分。使用IDE迅速建立一個應用程序的過程稱為快速反映開發。

C#.netC#2.0新特性

C#.net泛型

在我看來,泛型就是通過將數據類型參數化從而實現了代碼的更為靈活的複用,泛型的出現使得C#能夠使用同一段代碼來操作多種數據類型。泛型無疑是C#2.0最重大的改進,它的出現賦予了C#代碼更強的類型安全,更好的複用,更高的效率和更清晰的約束。

C#.net匿名方法

匿名方法允許我們將代碼直接與委託實例相關聯,使委託實例化工作更加直觀和方便。在我看來,這只是C#又多了一種語法格式而已,不再像以前必須將方法名傳給委託實例,而是又多了一種選擇。

C#.net迭代器

迭代器允許我們更加方便的編寫用於foreach語句的類型。在我看來,迭代器的出現只不過是改進了1.0中不便的可用foreach語句類型的編寫限制,簡化了一些接口。

C#.net局部類型

局部類型允許我們將一個類的代碼分別寫在不同的cs文件中。最典型的應用就是使用VS2005創建Form文件時,VS會自動將系統生成的代碼與用户代碼分開。局部類型通過partial關鍵字來聲明。

C#.net空屬類型

空屬類型是一種像int,一樣可以為空的變量類型。本質上是一種泛型的應用,是System .Nullable<>的一種類型實例化。

C#.net靜態類

:靜態類是隻用於包含靜態成員的類型,它既不能實例化,亦不能被繼承。

C#.netC#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.WriteLine
varanonymousType2=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方法,以將初始值列表中的所有元素加入到集合中,這裏我們只是簡單將初始值列表中的元素輸出到控制枱。
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表達式,就是大量運用擴展方法來實現數據查詢的。
8:Linq查詢表達式
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=frompinpersons
wherep.Age<=24
selectp;
foreach(varpersoninresults)
{
Console.WriteLine
Console.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=fromcincustomers
wherec.City=="China"
fromoinc.Orders
whereo.OrderDate.Year>=2007
selectnew{o.OrderNo,o.OrderDate,o.OrderName};
foreach(varcustomerinsomeCustomers)
{
Console.WriteLine(customer.OrderName+","+
customer.OrderDate.ToString("D")
);
}
}
}
從上面的例子中,我們可以看到Linq查詢的強大特性,它允許我們進行簡單查詢,或者進行更為複雜的多重連接查詢。且查詢的結果還可以是自定義的匿名類型。

C#.net控件

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,ActiveReportsMultiRow等。