名稱 |
用做類 |
用做類成員 |
Publicios |
該類型對全部程序集是可見的 |
成員能夠由全部程序集的全部⽅法訪問 |
Protected internal |
|
成員能夠由所在類型及其嵌套類型、全部派⽣類型 (不限程序集)、類型所在程序集的全部⽅法訪 問。 |
Internal |
該類型僅在程序集內部可見以及友元程序 集可見 |
成員可由當前程序集中的全部⽅法訪問 |
Protected |
|
成員只能由定義該成員類型中的⽅法、該類型的所 有嵌套類型的⽅法、或者該類型的⼀個派⽣類型 (不限程序集)的⽅法訪問 |
Private |
|
成員只能由定義該成員的類型中的⽅法或者該類型 的全部嵌套類型中的⽅法訪問 |
組件版本控制修飾符表:git
名稱 |
用做類 |
用做方法、屬性、事件 |
⽤做常量/字段 |
Abstract |
表⽰該類型不能構建實例 |
表⽰在構建派⽣類的實例以前派⽣類 型必須實現這個成員 |
|
Virtual |
|
表⽰這個成員能夠由派⽣類型重寫 |
|
Override |
|
表⽰派⽣類型重寫了基類型的成員 |
|
Sealed |
表⽰該類型不能⽤做基類 |
表⽰該成員不能被派⽣類型重寫 |
|
new |
應⽤於嵌套類型、⽅法、屬性、事件、常量或字段時,表⽰該成員與基類中相似的成員沒有關係 |
|
靜態類(static class):靜態類是不須要實例化,僅擁有靜態成員的類型。靜態類不⽀持接⼜,這是由於只有使⽤類的實 例的時候才調⽤類的接⼜⽅法。靜態類型只包括靜態成員,靜態類本⾝不能⽤做字段、⽅法參數或者局部變量。
部分類(partial class):爲了將⼀個類分佈在多個⽂件中編輯⽽採⽤partial修飾符,它們在編譯後成爲⼀個類。
索引器(indexer):索引器是⼀種參數化的成員屬性。索引器不⽀持靜態類型。索引器的做⽤是爲類型向外界間接提供 內部的集合成員。
例:
public object this[int x]{get;set;},public object this[int x,int y]{get;set;}
可變參數⽅法:以params關鍵字修飾的參數稱爲可變參數,它容許輸⼊數量不定的參數來調⽤⽅法。
例:
Public static double GetAvg(params double[] list){…}; GetAvg(1,2,12,4,3.2);GetAvg(1,57.3);
基類初始化(initializer)調⽤:⼦類在實例化時能夠⼀並調⽤基類的構造函數。這在多個類共享基類構造函數設置的⼀ 些公共成員屬性時更便利。
例:
Public class ClassA
{
public ClassA(int a,string b){…}
}
Public class ClassB:ClassA
{
public ClassB(int a,string b,bool c):base(a,b){…}
}
類型的私有構造函數常被⽤於只經過靜態⽅法和字段來提供功能的類型。採⽤私有構造函數的類不能被外部類實例化, 但能夠在內部實例化。
靜態構造函數⽤於初始化靜態成員,也只能訪問靜態成員,無論類型被實例化多少次,靜態構造函數只執⾏⼀次。
C# 特性標記的使用
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true)]
public class CustomerAttribute:Attribute
{
public String Name{get;set;}
}
使用反射獲取特性標記值
[CustomerAttribute(){Name="Sample"}]
public class Sample(){}
Sample o = new Sample();
Type ot = typeof(o);//typeof(t)
ot.GetCustomAttributes();
C# 匿名擴展方法
public class A
{
public A();
public void M1();
}
public static class M
{
public static M2(this A a )
{
//do sth.
}
}
(五) 集合類型 Array\ArrayList\List\HashTable(哈希表)\Dictionary(字典)\Stack(堆棧)\Queue(隊列)
Array類型:是實現數組的基類,只有系統和編譯器能夠派⽣。Array提供CreateInstance⽅法進⾏後期綁定,沒有公共構 造函數。如下都是聲明數組的⽅式:
Array my1DArray=Array.CreateInstance( typeof(Int32), 5 );
Int32[] my2DArray = new Int32[5]{1,2,3,4,5}
ArrayList類型:是⼤⼩按需⾃動增長的Array實現,實現了IList接口。如下是ArrayList常見⽤法:
ArrayList myAL = new ArrayList();
myAL.Add("Hello");
myAL.Add("World"); myAL.Add("!");
HashTable: 表⽰鍵/值對的集合,這些鍵/值對根據鍵的哈希代碼進⾏組織。
例:
public static void Main() {
// Creates and initializes a new Hashtable.
Hashtable myHT = new Hashtable();
myHT.Add("First", "Hello");
myHT.Add("Second", "World");
myHT.Add("Third", "!");
// Displays the properties and values of the Hashtable.
Console.WriteLine( "myHT" );
Console.WriteLine( " Count: {0}", myHT.Count );
Console.WriteLine( " Keys and Values:" );
PrintKeysAndValues( myHT );
}
public static void PrintKeysAndValues( Hashtable myHT ) {
Console.WriteLine( "\t-KEY-\t-VALUE-" );
foreach ( DictionaryEntry de in myHT )
Console.WriteLine("\t{0}:\t{1}", de.Key, de.Value);
Console.WriteLine();
}
Dictionary:是HashTable的泛型實現
Stack:表⽰對象的簡單的後進先出⾮泛型集合。Stack 的容量是 Stack 能夠保存的元素數。Stack 的默認初始容量爲 10。 向 Stack 添加元素時,將經過從新分配來根據須要⾃動增⼤容量。Stack常被看成循環緩衝區。
Queue(隊列):是表⽰對象的先進先出集合,與Stack相反。隊列在按接收順序存儲消息⽅⾯⾮常有⽤,以便於進⾏順 序處理。此類將隊列做爲循環數組實現。存儲在 Queue 中的對象在⼀端插⼊,從另⼀端移除。
Queue 的容量是 Queue 能夠保存的元素數。Queue 的默認初始容量爲 32。向 Queue 添加元素時,將經過從新分配來根據 須要⾃動增⼤容量。
(六)泛型
泛型(generic)是CLR與編程語⾔提供的⼀種實現「算法重⽤」的機制。
例:
List sl = new List();sl.add(DateTime.Now);sl.add(DateTime.MinValue);
泛型對象設計⽤於管理在類型上成家族的集合,例如設計⼀個⼯⼚類型⽤於建立或修改基於某個接口演變的多個⼦類型 的對象。
例:
/// <summary>
/// 爲安全成員對象提供公共服務
/// </summary>
public abstract class SecurityMemberService<T> where T:ISecurityMember
{
public abstract T MemberLogin(string memberUserName,string memberPassword);
public abstract T MemberLogin(string memberEmail,string memberPassword);
public abstract bool MemberLogout(T member);
public abstract T CreateMember(T obj,SecurityMemberInfo info);
public abstract bool DeleteMember(T member);
public abstract T FindMemberByUserName(string userName);
public abstract T FindMemberByEmail(string email);
public abstract bool LockMember(T member);
public abstract bool UnlockMember(T member);
public abstract bool ChangePassword(string memberName, string oldPassword,string newPassword);
public abstract bool ChangePasswordQuestionAndAnswer(T member);
public abstract bool ResetPasswordAndUpdate(T member);
}
在上例中,SecurityMemberService類型封裝了⼀般對ISecurityMember類型的處理⽅法,類型參數T能夠是任意 實現了ISecurityMember接⼝的類型,這樣對這些類型的⼀般處理並不須要建立額外對應的⼯⼚類型。 注意:泛型類SecurityMemberService有⼀個對類型參數T的約束,它由where關鍵字指定。
在⾮泛型類中也能夠有泛型⽅法成員,一樣泛型⽅法也可有類型約束。
例:
Public class A
{
Void M1<T>(T obj){obj.ToString();}
Void M2<T>(T obj)where T:ClassB {obj.ToString();}
}
委託也能夠被設計成泛型,由於委託也能夠被看成⽅法的⼀種定義形式,即委託自己描述的是回調⽅法的定義。
例:
Delegate void EventHandler(Object sender,TEventArgs e)where TEventArgs:EventArgs;
上例定義的EventHandler要求回調⽅法中的參數e必須是EventArgs類型或是EventArgs的派⽣類型,TEventArgs 是⼀個類型參數,至關於常⻅的T。
(七)線程 (Threading、Lock、Monitor、Mutex)
線程概述:
線程分爲前臺線程和後臺線程,後臺線程不妨礙程序的終⽌。線程具備優先級,優先級⾼的線程會獲得更多的CPU時 間。多線程能夠提⾼對CPU時間的利⽤率,但會佔⽤更多的內存等資源。
線程安全:
Lock關鍵字能夠將⼀段代碼定義爲互斥段。互斥段在⼀個時刻內只容許⼀個線程進⼊執⾏,⽽其餘線程必須等待。若是 有⼀些任務每次只能交給⼀個線程去操做,就可使⽤Lock關鍵字將代碼定義爲互斥段。
例:
Lock(this)
{
//do anything
}
Monitor 類經過向單個線程授予對象鎖來控制對對象的訪問。對象鎖提供限制訪問代碼塊(一般稱爲臨界區)的能⼒。當 ⼀個線程擁有對象的鎖時,其餘任何線程都不能獲取該鎖。還可使⽤ Monitor 來確保不會容許其餘任何線程訪問正在由 鎖的全部者執⾏的應⽤程序代碼節,除⾮另⼀個線程正在使⽤其餘的鎖定對象執⾏該代碼。
例:
Queue myQueue = new Queue();
Monitor.Enter(myQueue);
//能夠在當前線程下對myQueue作任何操做。
Monitor.Exit(myQueue)//釋放鎖
爲了保證在異常狀況下仍可釋放鎖,Monitor.Exit()⽅法能夠放在finally塊⾥。調⽤Monitor.Pulse()⽅法會通知預備隊列中的 線程能夠⽴即便⽤釋放的對象。
Mutex類是同步基元。當兩個或更多線程須要同時訪問⼀個共享資源時,系統須要使⽤同步機制來確保⼀次只有⼀個線程 使⽤該資源。
Mutex只向⼀個線程授予對共享資源的獨佔訪問權。若是⼀個線程獲取了互斥體,則要獲取該互斥體的第⼆個線程將被掛 起,直到第⼀個線程釋放該互斥體。已命名的系統互斥體(Mutex)在整個操做系統中均可見,可⽤於同步進程活動。
與Monitor類不一樣,Mutex可與WaitHandle⼀起構成「等待機制」,Mutex還能夠穿越應⽤程序域。
例:
class Test
{
// Create a new Mutex. The creating thread does not own the
// Mutex.
private static Mutex mut = new Mutex();
private const int numIterations = 1;
private const int numThreads = 3;
static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread myThread = new Thread(new ThreadStart(MyThreadProc));
myThread.Name = String.Format("Thread{0}", i + 1);
myThread.Start();
}
// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}
private static void MyThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
private static void UseResource()
{
// Wait until it is safe to enter.
mut.WaitOne();
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(500);
Console.WriteLine("{0} is leaving the protected area\r\n",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
}
}
(八) C# 面向對象編程、繼承、多態、接口、委託、事件
基本概念
⾯向對象編程(Object –Oriented Programming,OOP),抽象、繼承和多態是OOP編程語⾔的三⼤要素。
繼承:類繼承的重要特性是,在但願出現基類型實例的任何地⽅,均可以替換成派⽣類型的實例。相似地,接口繼承容許在但願出現已命名接口類型的實例的任何地⽅,均可以替換成實現接口的⼀個類型的實現。
多態:指的是多個類型的對象對同⼀消息作出各⾃的處理。多態是⼦類對⽗類的⽅法進⾏重寫或替換⽽實現的。
接口:接口是⼀組已命名的⽅法簽名,在接口內還能夠定義事件和屬性,它們在本質上也是⽅法。C# 要求接口⽅法標記爲 Public。接口的關鍵價值在於隱藏類型的設計細節,即外部對象不依賴當前對象的內部細節。
接口特性
接口⽅法的隱式實現:當⽅法簽名與繼承的接口中的簽名⼀致,而且是public或者是viture修飾的⽅法都視爲隱式實現了接口⽅法。
例:
Internal sealed class SimpleType:IDisposable
{
Public void Dispose(){Console.WriteLine(「Dispose」);}
}
接口⽅法的顯式實現:以接口類型名稱做爲⽅法前綴時,建立的是⼀個顯式接口⽅法實現(explicit interface method implementation,EIMI)。⼀個EIMI⽅法不容許標記訪問性(⽐如公共或私有),也不能被標記爲virture,因⽽也不能被重 寫。顯⽰接口⽅法會損害性能,應當謹慎使⽤。
例:
Internal sealed class SimpleType:IDisposable
{
Public void Dispose(){….}
Void IDisposable.Dispose(){….}//顯式
}
對顯式接口的調⽤,須要經過⼀個接口類型的變量來進⾏。
例:
SimpleType st = new SimpleType();
IDisposable d = st;
d.Dispose();
泛型接口有以下優勢:
一、使用接口方法變爲強類型。
二、泛型接口在操做值類型時,會減小裝箱操做。
三、類能夠實現同一個接口若干次,只要使用不一樣的類型參數。
例:
Public sealed class Number:IComparable<Int32>,IComparable<String>
{
Private int32 m_val =5;
//實現IComparable<Int32>
Public Int32 CompareTo(Int32 n){return m_val.CompareTo(n);}
//實現IComparable<String>
Public Int32 CompareTo(String s){return m_val.CompareTo(Int32.Parse(s));}
}
委託
委託是.NET中的回調機制。將一個方法綁定到一個委託時,C#和CLR容許引用類型的協變(covariance)和反協變(contra-variance)。協變是指一個方法能返回一個從委託的返回類型派生出來的類型。反協變是指一個方法的參數類型能夠是委託的參數類型的基類。但協變對於返回值類型或void的方法不適用。
例:
//MyCallback委託
Delegate object MyCallback(FileStream s);
//SomeMethod⽅法
String SomeMethod(Stream s);
上例中,SomeMethod的返回類型(String)繼承⾃委託返回類型(Object),這種協變是容許的。SomeMethod的參數類型
(Stream)是委託的參數類型(FileStream)的基類。這種反協變是容許的。
鏈式委託指的是⽤⼀個委託回調多個⽅法,即⼀系列委託對象組成的集合。Delegate的公共靜態⽅法Combine⽤於添加⼀ 個委託到委託鏈,Remove⽅法⽤於從鏈中刪除⼀個委託對象。在C#中內置的+=與-=操做符簡化了這些操做。
例:
Internal delegate void Feedback(int32 value);
Feedback fb1 = new Feedback(….);
Feedback fb2 = new Feedback(….);
fbChain =(Feedback)Delegate.Combine(fbChain,fb1);
fbChain =(Feedback)Delegate.Combine(fbChain,fb2);
⼀組委託是按順序執⾏的,若是他們帶有返回值,只能獲得最後⼀個委託的返回值,若是其間有委託⽅法出現致命錯誤,其它委託就⽆法執⾏。爲了克服這些問題,產⽣了MulticastDelegate類,它的GetInvocationList⽅法⽤於顯式調⽤鏈中的每 ⼀個委託,並使⽤符合⾃⼰需求的任何算法。MulticastDelegate類是特殊的類型,只能由系統派⽣,Delegate類已經具有了 MulticastDelegate的能⼒。
委託的便捷實現:
1. 不構造委託對象
例:
internal sealed class AClass
{
public static void CallbackWithoutNewingADelegateObject()
{
ThreadPool.QueueUserWorkItem(SomeAsyncTask,5);
}
private static void SomeAsyncTask(Object o)
{
Console.WriteLine(o);
}
}
上例中ThreadPool類的靜態⽅法QueueUserWorkItem指望接收⼀個WaitCallback委託對象引⽤,該對象又包含⼀個 SomeAsyncTask⽅法引⽤。由於C#編譯器可以⾃⼰進⾏推斷,因此咱們能夠省略構造WaitCallback對象的代碼。
2. 不定義回調⽅法
例:
internal sealed class AClass
{
public static void CallbackWithoutNewingADelegateObject()
{
ThreadPool.QueueUserWorkItem(delegate(Object obj){Console.WriteLine(obj);},5)
}
}
上例中⽤了⼀段代碼塊替代了回調⽅法名,編譯器會⾃動在類中增長⼀個通過命名的基於此代碼塊的回調⽅法。
3. 不指定回調⽅法的參數
例:
button1.Click += delegate(Object sender,EventArgs e){MessageBox.Show(「The Button was clicked」);}
//因爲上述⽅法中沒有⽤到sender與e兩個參數,可簡寫爲:
button1.Click+=delegate{MessageBox.Show(「 The Button was clicked」);}
4. 不須要將局部變量⼈⼯封裝到類中,便可傳給⼀個回調⽅法
事件
事件:在.NET中事件(event)是類的成員,與成員屬性和⽅法⼀樣。類型的事件,是對外提供的⾃⾝狀態的通知。外部類 型經過訂閱的形式與事件的發佈類型進⾏協做。將事件與處理⽅法關聯起來的是委託。.NET中⽤event關鍵指定特定的委託 來爲事件作出響應,這樣作能夠限制其它⽅法對委託的調⽤(在內部定義委託爲私有的,經過event公開,所以外部⽆法訪 問委託中的⽅法)。
設計線程安全的事件,必須顯⽰地控制事件的訂閱與註銷。
例:
internal class MailManager
{
//建立⼀個做爲線程同步鎖的私有實例字段
private readonly Object m_eventLock = new Object();
//增長⼀個引⽤ 委託鏈表頭部的私有字段
private EventHadler<NewMailEventArgs> m_NewMail;
//增長⼀個事件成員
public event EventHandler<NewMailEventArgs> NewMail
{
//顯式實現add
add
{
//加私有鎖,並向委託鏈表增長⼀個處理程序以‘value’爲參數
lock(m_eventLock){m_NewMail+=value;}
}
//顯式實現remove
remove
{
//加私有鎖,並向委託鏈表移除⼀個處理程序以‘value’爲參數
lock(m_eventLock){m_NewMail -= value;}
}
}
//定義⼀個負責引起事件的⽅法,來通知已訂閱事件的對象事件已經發⽣,若是類是封裝的
//則須要將⽅法聲明爲private和non-virtual
proteted virtual void OnNewMail(NewMailEventArgs e)
{
//出於線程安全考慮,將委託字段保存到⼀個臨時字段中
EventHadler<NewMailEventArgs> temp = m_NewMail;
if(temp!=null){temp(this,e);}
}
//將輸⼊轉化爲但願的事件
public void SimulateNewMail(String from,String to,String subject)
{
//構建⼀個對象存放給事件接收者的信息
NewMailEventArgs e = new NewMailEventArgs(from,to,subject);
//引起
OnNewMail(e);
}
}
委託與事件
關鍵字「event」是個修飾詞,在絕⼤多數的情形中,被指定爲委託(delegate)的對象和被指定爲事件(event)的對象是能夠互換的。然⽽,事件還有特殊之處:
● 事件就像⼀個委託類型的字段。該字段引⽤了⼀個表明事件處理器的委託,這些處理器是被添加到事件上的;
● 事件只能在聲明它的類中被調⽤,⽽全部能見到委託的地⽅均可以使⽤委託;
● 事件能夠被包含在接口中⽽委託不能夠;
● 事件有可被重寫的Add和Remove存取(acccessor)⽅法;
(九)、Linq表達式、異步處理
LINQ
語言集成查詢 (LINQ) 是一系列直接將查詢功能集成到 C# 語言的技術統稱,好比涵蓋:SQL 數據庫查詢、XML 文檔查詢、List對象查詢、Array對象查詢、String對象查詢……。 藉助 LINQ,查詢成爲了最高級的語言構造,就像類、方法和事件同樣。
示例:
class LINQQueryExpressions
{
static void Main()
{
// Specify the data source.
int[] scores = new int[] { 97, 92, 81, 60 };
// Define the query expression.
IEnumerable<int> scoreQuery =
from score in scores
where score > 80
select score;
// Execute the query.
foreach (int i in scoreQuery)
{
Console.Write(i + " ");
}
}
}
// Output: 97 92 81
更詳細的Linq用法請參考:
異步處理
異步是 .NET 中充分使用處理器核心資源的機制,異步機制直接處理多個核心上的阻塞 I/O 和併發操做以提升系統執行效率。
.NET 異步的特色:
一、等待 I/O 請求返回的同時,可經過生成處理更多請求的線程,處理更多的服務器請求。
二、等待 I/O 請求的同時生成 UI 交互線程,並經過將長時間運行的工做轉換到其餘 CPU 核心,讓 UI 的響應速度更快。
使用基於 .NET 任務的異步模型可直接編寫綁定 I/O 和 CPU 的異步代碼。 該模型由 Task 和 Task<T> 類型以及 C# 和 Visual Basic 中的 async 和 await 關鍵字公開。 (有關特定語言的資源,請參見另請參閱部分。)
Task是用於實現稱之爲併發 Promise 模型的構造。 簡單地說,它們「承諾」,會在稍後完成工做。
Task 表示不返回值的單個操做。
Task<T> 表示返回 T 類型的值的單個操做。
Task在當前線程上執行,且在適當時會將工做委託給操做系統。 可選擇性地經過 Task.Run API 顯式請求任務在獨立線程上運行。
示例:
//定義一個基於Task的異步方法
public Task<string> GetHtmlAsync()
{
// Execution is synchronous here
var client = new HttpClient();
}
//第二個異步方法
public async Task<string> GetFirstCharactersCountAsync(string url, int count)
{
// Execution is synchronous here
var client = new HttpClient();
// Execution of GetFirstCharactersCountAsync() is yielded to the caller here
// GetStringAsync returns a Task<string>, which is *awaited*
var page = await client.GetStringAsync(url);
// Execution resumes when the client.GetStringAsync task completes,
// becoming synchronous again.
if (count > page.Length)
{
return page;
}
else
{
return page.Substring(0, count);
}
}
//調用示例
var str = await GetHtmlAsync();
var str2 = await GetFirstCharactersCountAsync("https://www.dotnetfoundation.org",100);
更深刻地瞭解 .NET 上的異步編程
3、.NET 上的 Web 開發: ASP.NET Core
.NET上的Web解決方案由ASP.NET Core 框架實現,某種程度上你能夠將之理解爲Java界的Spring MVC。ASP.NET 是經典.NET上的Web解決方案,咱們建議新的Web應用應該選擇ASP.NET Core。
當前Web開發存在兩種主要的風格:MVC,Web API。MVC指的是模型--視圖--控制器的Web程序設計模式,而Web API指的是面向RESTful API場景的Web程序設計模式,它僅提供API調用的響應而不關心視圖。
ASP.NET Core
ASP.NET Core MVC 框架由以下基本組件構成:
路由
模型綁定
模型驗證
依賴關係注入
篩選器
區域
Web API
Razor 視圖引擎
強類型視圖
標記幫助程序
視圖組件
控制器:ASP.NET Core MVC 的Web請求入口是由Controller類型或其子類型的公共方法實現的,通常狀況下每一個請求入口都是一部分業務邏輯代碼的聚合。
例:
public class DefaultController : ControllerBase
{
public ActionResult<string> Index()
{
return "hello,world";
}
}
路由:ASP.NET Core MVC 創建在 ASP.NET CORE 的路由之上,是一個功能強大的 URL 映射組件,可用於生成具備易於理解和可搜索 URL 的應用程序。 它可以讓你定義適用於搜索引擎優化 (SEO) 和連接生成的應用程序 URL 命名模式,而不考慮如何組織 Web 服務器上的文件。 可使用支持路由值約束、默認值和可選值的方便路由模板語法來定義路由。
例:
routes.MapRoute(name: "Default", template: "{controller=Home}/{action=Index}/{id?}");
模型:ASP.NET Core MVC 模型綁定將客戶端請求數據(窗體值、路由數據、查詢字符串參數、HTTP 頭)轉換到控制器能夠處理的對象中。 所以,控制器邏輯沒必要找出傳入的請求數據;它只需具有做爲其操做方法的參數的數據。
例:
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) { ... }
模型驗證:ASP.NET Core MVC 經過使用數據註釋驗證屬性修飾模型對象來支持驗證。 驗證屬性在值發佈到服務器前在客戶端上進行檢查,並在調用控制器操做前在服務器上進行檢查。
例:
using System.ComponentModel.DataAnnotations;
public class LoginViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
Razor視圖引擎: Razor 是一種緊湊、富有表現力且流暢的模板標記語言,用於使用嵌入式 C# 代碼定義視圖。 Razor 用於在服務器上動態生成 Web 內容。 能夠徹底混合服務器代碼與客戶端內容和代碼。咱們能夠在MVC工程中,往Controller添加請求入口的View文件,這些View文件表明視圖文件(.cshtml),這些文件默認使用Razor視圖引擎來實現服務端渲染視圖。
例:
Index.cshtml:
<!-- 單行代碼塊 -->
@{ var myMessage = "Hello World"; }
<!-- 行內表達式或變量 -->
<p>The value of myMessage is: @myMessage</p>
<!-- 多行代碼塊 -->
@{
var greeting = "Welcome to our site!";
var weekDay = DateTime.Now.DayOfWeek;
var greetingMessage = greeting + " Today is: " + weekDay;
}
<p>The greeting is: @greetingMessage</p>
Web API: ASP.NET Core 支持使用 C# 建立 RESTful 服務,也稱爲 Web API。 Web API 使用控制器響應這些請求,Web API 中的控制器是派生自 ControllerBase 的類。
例:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
public ActionResult<Pet> Create(Pet pet)
{
pet.Id = _petsInMemoryStore.Any() ? _petsInMemoryStore.Max(p => p.Id) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById),
new { id = pet.Id }, pet);
}
}
SignalR: ASP.NET Core SignalR 是一個開源代碼庫,它簡化了嚮應用添加實時 Web 功能的過程。 實時 Web 功能使服務器端代碼可以即時將內容推送到客戶端。
SignalR 的適用對象:須要來自服務器的高頻率更新的應用。
例如:
遊戲、社交網絡、投票、拍賣、地圖和 GPS 應用;
儀表板和監視應用;
協做應用,例如白板應用和團隊會議軟件;
須要通知的應用, 社交網絡、電子郵件、聊天、遊戲、行程警示以及許多其餘應用都使用通知;
SignalR 提供了一個用於建立服務器到客戶端遠程過程調用(RPC)的 API。 RPC 經過服務器端 .NET Core 代碼調用客戶端上的 JavaScript 函數。
如下是 ASP.NET Core SignalR 的一些功能:
一、自動管理鏈接。
二、向全部鏈接的客戶端廣播消息。 例如,聊天室。
三、將消息發送到特定的客戶端或客戶端組。
四、擴展以處理增長的流量。
4、.NET 上的ORM
EF6 & EF Core
EntityFramework 6.x (EF6) 是經典 .NET上的 ORM 框架,它功能全面在Windows上運行穩定。
EntityFramework Core (EF Core) 是 EntityFramework 的跨平臺移植版本,目前功能上與 EF6 仍有差距,能夠知足絕大部分 CRUD 操做。
下圖是 EF6 與 EF Core 在數據庫支持上的對比:
其它ORM
dapper 是Stack Overflow貢獻的輕量級 ORM 框架,兼容.NET Core 和 .NET 4.5x,它直接擴展了.NET Connection 對象。
SmartSql 是一個包括ORM及延伸功能的數據、緩存讀寫與配置框架。
以上介紹的主要的ORM工具均可以在Github上找到其官方主頁。
5、.NET 微服務和容器化
.NET Core 是最先響應微服務與容器化部署的技術平臺。.NET 團隊在Docker Hub 官網上維護着全部主要的 .NET Core 版本的 Docker 鏡像。
你能夠在這個連接上找到這些鏡像: https://hub.docker.com/_/microsoft-dotnet-core
值得一提的是,.NET Core 在 Docker 上的性能表現超過了大部分其餘同類技術平臺。例如使用 Raygun 工具測試相同 Linux 環境的上運行的 Node.js 與 .NET Core 的性能對比,.NET Core 的性能是 Node.js 的2000%。
.NET Core 是天生爲雲計算優化的技術平臺,有着優良的可伸縮性,併兼容主流的雲計算平臺,好比 Azure、AWS、阿里雲。
上圖是 .NET Core 上實現的微服務與 docker 容器部署的典型架構示例github
6、.NET平臺與Java平臺的互換性
|
.NET |
Java |
包管理web |
nuget |
Maven |
Web場景開發 |
ASP.NET
ASP.NET Core
|
Spring Boot |
ORM |
EntityFramework 6.x
EntityFramework Core
dapper
NHibernate
SmartSql
|
Hibernate
Mybatis
|
單元測試 |
MSUnit
XUnit.net
|
JUnit |
Android/ios 開發 |
Xamarin |
Android SDK
RoboVM
|
Windows 開發 |
.NET Framework 4.x
.NET Core 3.0+
Mono |
Oracle JDK
Open JDK (free)
|
Mac OS 開發 |
Mono
Xamarin/.NET Core
|
Oracle JDK
Open JDK(free)
|
linux開發 |
Mono
.NET Core
|
Oracle JDK
Open JDK(free)
|
docker支持 |
.NET Core
ASP.NET Core
Mono
|
Oracle JDK
Open JDK(free)
|
AI/數據分析 |
ML.net
ONNX Runtime
Microsoft Cognitive Toolkit(CNTK)
tensorflow.net
.NET for Apache Spark
|
Eclipse Deeplearning4j
Apache OpenNLP
Java-ML
Spark
Flink
Kafka
Storm
|
遊戲開發 |
Unity (C#語言)
MonoGame
CRYENGINE
|
|
IoT |
.NET Core |
Open IoT Stack for Java |
以上關於 .NET 平臺及 Java 平臺的比較信息來源於一小部分有表明性的技術棧,僅供參考。
感謝 .NET 社羣中的朋友幫忙審校。
參考連接: