LINQ查詢表達式以from子句開始,以select或者group子句結束。在這兩個子句之間能夠跟零個或者多個from、let、where、join或者orderby子句。html
static void LINQQuery() { //Formula1.GetChampions()返回一個列表,quer變量只是一個賦值語句,只有使用了foreach纔會執行查詢 var query = from r in Formula1.GetChampions() where r.Country == "Brazil" orderby r.Wins descending select r; foreach (var r in query) { Console.WriteLine("{0:A}", r); } }
11.1.3擴展方法python
若是有類的源碼,繼承就能夠給對象添加方法。但若是沒有源代碼,則可使用擴展方法,它容許改變一個類,但不須要該類的源代碼。
擴展方法是靜態方法,它是類的一部分,但實際上沒有放在類的源代碼中。假定PhoneCusStruct類須要一個Add()方法,但不能修改源代碼,就能夠建立一個靜態類,把Add()方法添加爲一個靜態方法算法
public static class PhoneExtension { public static void Add(this PhoneCusStruct phoneCusStruct,string phone) { // }
注意擴展方法的第一個參數是要擴展的類型,它放在this關鍵字的後面。這告訴編譯器,這個方法是PhoneCusStruct類型的一部分。在這個例子中,PhoneCusStruct是要擴展的類型。在擴展方法中,能夠訪問所擴展類型的全部公有方法和屬性。
調用:PhoneCusStruct p =new PhoneCusStruct();
p.Add();//即便方法是靜態方法,也須要使用實例方法的語法。
若是擴展方法與類中的某個方法同名,就不會調用擴展方法。類中已有的任何實例方法優先。數據庫
編譯器會轉換LINQ查詢,以調用方法而不是LINQ查詢。LINQ爲IEnumerable<T>接口提供了各類擴展方法(擴展方法在上面介紹到),以便用戶在實現了該接口的任意集合上使用LINQ查詢。
定義LINQ擴展方法的一個類是System.Linq名稱空間中的IEnumerable。只須要導入這個名稱空間,就打開了這個類的擴展方法的做用域。下面是Where()擴展方法的實現代碼:編程
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate) { foreach(TSource item in source) { if(predicate(item)) { yield return item; } } }
由於Where()做爲一個泛型方法,因此它能夠用於包含在集合中的任意類型。實現了IEnumerable<T>接口的任意集合都支持它。安全
相關連接框架
其因相關使用在應用環境中再學習!這裏先作了解異步
Dynamic Language Runtime動態語言容許添加動態語言,如Ruby和Python.async
dynamic的對象能夠在運行期間改變其類型.其類型是有用的,但它是有代價的!異步編程
dynamic dyn; dyn = 100; Console.WriteLine(dyn.GetType()); //輸出System.int32 Console.WriteLine(dyn); //輸出100 dyn = "This is a string"; Console.WriteLine(dyn.GetType()); //輸出System.String Console.WriteLine(dyn); //輸出This is a string
利用腳本完成工做,相關應用相對少,可請選讀 因要了解python語言,暫時跳過
13.1
一、Invoke() 調用時,Invoke會阻止當前主線程的運行,等到 Invoke() 方法返回才繼續執行後面的代碼,表現出「同步」的概念。
二、BeginInvoke() 調用時,當前線程會啓用線程池中的某個線程來執行此方法,BeginInvoke不會阻止當前主線程的運行,而是等當前主線程作完事情以後再執行BeginInvoke中的代碼內容,表現出「異步」的概念。
IAsyncResult rtn = 委託變量.BeginInvoke(……); // 啓動異步調用
三、EndInvoke() ,在想獲取 BeginInvoke() 執行完畢後的結果時,調用此方法來獲取。
用於保存方法結果的變量=委託變量.EndInvoke(rtn); // 阻塞並等待異步調用結束
static string Greeting(string name) //Greeting同步方法 { Console.WriteLine("運行時訪問的線程是:{0}與任務是:{1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId); Thread.Sleep(3000); return string.Format("Hello, {0}", name); } static Task<string> GreetingAsync(string name) //異步方法GreetingAsync返回的是Task<string> { return Task.Run<string>(()=> { return Greeting(name);
Console.WriteLine("running greetingasync in thread {0} and task {1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId);
});
}
private async static void CallerWithAsync() { Console.WriteLine((await GreetingAsync("Stephanie")); //async修飾符只能用於返回Task或Void的方法 }
ContinueWith方法定義了任務完成後就調用的代碼(注:如任務清理工做可等)
private static void CallerWithContinuationTask() { Console.WriteLine("CallerWithContinuationTask線程爲 {0} 任務 {1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId); var t1 = GreetingAsync("Stephanie"); t1.ContinueWith(t => { string result = t.Result; // 訪問任務返回的結果 Console.WriteLine(result); Console.WriteLine("完成後的運行線程 {0} 任務 {1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId); }); } //輸出爲: // CallerWithContinuationTask線程爲 1 任務 // running greetingasync in thread 3 and task 1 // 運行時訪問的線程是:3與任務是:1 // Hello, Stephanie // 完成後的運行線程 4 任務 2
上下文簡單理解爲當時的環境便可,環境能夠包括當時程序狀態以及變量的狀態,例如線程切換的時候在內核會發生上下文切換,這裏的上下文就包括了當時寄存器的值,把寄存器的值都保存起來,等下次該線程又獲得CPU時間的時候再恢復寄存器的值,這樣線程才能正確的運行.
//若是不加上下文,那麼就是以對象爲線程鎖定區域,若是加上下文,那麼就是以邏輯上下文爲鎖定區域 [Synchronization(SynchronizationAttribute.REQUIRED, true)] class synchronizationClass : ContextBoundObject { public void Start() { MessageBox.Show(Thread.CurrentThread.Name); } }
由於是使用SynchronizationAttribute來建立鎖的,因此第一句[Synchronization(SynchronizationAttribute.REQUIRED, true)] 是必不可少的。
又由於是爲ContextBoundObject對象建立鎖,因此對象必須是ContextBoundObject,故必須繼承ContextBoundObject。
二者缺一不可。測試:
synchronizationClass myclass = new synchronizationClass(); Thread thread = new Thread(new ThreadStart(myclass.Start)); thread.Name = "thread1";
Thread thread2 = new Thread(new ThreadStart(myclass.Start)); thread2.Name = "thread2"; thread.Start(); thread2.Start();
現象是thread1先彈框,點擊肯定後再彈thread2,緣由就是整個對象都是一個鎖,就是在thread1沒處理完,thread2是沒法進行操做的。
因此呢,上下文同步域會將整一個上下文所有鎖定,就是說整個類都成爲了一個鎖,在線程1未走出該類,線程2就沒法進入該類。
加入我把[Synchronization(SynchronizationAttribute.REQUIRED, true)]或者不繼承ContextBoundObject發現此時的現象是thread1和thread2都會彈出框。
這就是鎖與不鎖的區別了。
1.按順序調用異步方法 (按順序使用await)
2.使用組合器
Task<string> t1 = GreetingAsync("Stephanie");await Task.WhenAll(t1, t2);//全部提供的任務都已完成時,纔會返回Tack
Task.WhenAny()//在其中一個任何提供的任務已完成時,就會返回Tack
轉換爲基於任務的異步模式 基於任務模式的異步的相關知識點
private static async void ConvertingAsyncPattern() { string r = await Task<string>.Factory.FromAsync<string>(BeginGreeting, EndGreeting, "Angela", null);//建立一個任務,它表示符合異步編程模型模式的成對的開始和結束方法。 Console.WriteLine(r); } /// <summary> /// 從同步方法中藉助委拖,建立一個異步方法 /// </summary> private static Func<string, string> greetingInvoker = Greeting; /// <summary> /// 異步模式 /// </summary> /// <param name="name">異步模式名</param> /// <param name="callback">異步操做的狀態</param> /// <param name="state"></param> /// <returns></returns> static IAsyncResult BeginGreeting(string name, AsyncCallback callback, object state) { return greetingInvoker.BeginInvoke(name, callback, state); } static string EndGreeting(IAsyncResult ar) { return greetingInvoker.EndInvoke(ar); }
static async Task ThrowAfter(int ms, string message) { await Task.Delay(ms); throw new Exception(message); } private static async void HandleOneError() { try { await ThrowAfter(2000, "first");//若是不加入await的話 就沒法捕捉異常! } catch (Exception ex) { Console.WriteLine("handled {0}", ex.Message); } }
Task taskResult = null; try { Task t1 = ThrowAfter(2000, "first"); Task t2 = ThrowAfter(1000, "second"); await (taskResult = Task.WhenAll(t1, t2)); } catch (Exception ex) { // 第一個任務的異常信息,只顯示在全部等待 Console.WriteLine("handled {0}", ex.Message); foreach (var ex1 in taskResult.Exception.InnerExceptions) { Console.WriteLine("inner exception {0} from task {1}", ex1.Message, ex1.Source); } }
private CancellationTokenSource cts = new CancellationTokenSource(); private void OnCancel(object sender, RoutedEventArgs e) { if (cts != null) cts.Cancel(); }
private async void OnTaskBasedAsyncPattern(object sender,RoutedEventArgs e) { cts =new CancellationTokenSourcs(); try{ foreach(var req in GetSearchRequests()) var Client =new HttpClient(); var response = await Client.GetAsync(req.Url, cts.Token);//用以異步操做的 HTTP 完成選項和取消標記發送 GET 請求到指定的 URI。 string resp = await Response.Content.ReadAsStringAsync(); } catch (OperationCanceledException ex) { MessageBox.Show(ex.Message); } }
13.5.3取消自定義任務
沒測試!!跳過
private async void test() { await Task.Run(() => { var images = req.Parse(resp); foreach(var image in images) { cts.Token.ThrowIfCancellationRequested(); searchInfo.list.add(image); } }, cts.Token); }
int類型爲爲4個字節,即佔用4個指針位. double佔8個字節
參考C的示例
#include<stdio.h> int *fun1(){ int a; return &a;} int fun2(){ int b=6; } int main(){ int *p=fun1(); fun2(); printf("%d\n",*p);}
局部變量在函數調用完就會擦除(應該跟程序的聯繫),但是你使用局部變量時存放的是棧段,棧段的順序是後進先出,而你恰好申請了相同大小的變量空間,系統直接就把那塊空間又分配給你了,而裏面的內容並沒擦除。
託管程序會自動更新地址,壓縮堆造成一個鏈接的內存塊
GC是一個垃圾回收機制 它主要是回收 託管對象 而不會回收 非託管對象 就像你使用某些非託管數據庫連接對象的時候 就須要手動關閉 這些須要手動關閉的對象就是非託管對象 而這個就不是在GC管理範圍以內
另外要說一下的是 GC這個東西很調皮 有時候GC的回收是沒有固定時間的 隨機的 因此 有時候咱們須要手動關閉一些比較大的託管對象來提升性能
14.3.2IDisposable接口
在C#中,推薦使用System.IDisposable接口替代折構函數
class ResouerceGobbler : IDisposable { public void Dispose() { } }
ResouerceGobbler theInstance = new ResouerceGobbler(); //使用
//程序
theInstance.Dispose() //釋放
若是處理過程當中出現異常,沒有釋放,因此應該使用
ResouerceGobbler theInstance = null; try { theInstance = new ResouerceGobbler(); //程序
} finally { if (theInstance != null) { theInstance.Dispose(); } }
以上代碼有點混亂,因此有了下面的語法
using( ResouerceGobbler theInstance = new ResouerceGobbler()) { //程序 }
close()是調用dispose()的方法實現的
使用指針的主要緣由
1.向後兼容性
調用本地WindowsAPI函數,可使用DllLmport聲明,以免使用指針
2.性能
unasfe int GetSomeNumber(){} //表示這是一個不安全的方法! 也能夠標記class或參數虛方法等,不能在局部變量自己標記爲unsafe
若是要使用不安全變量,須要在不安全的方法中聲明和使用它
VS可在項目屬性窗口的Build選項中找到不安全代碼的選項
二.指針的語法(命名時前面是小寫p)
int* pWidth; //*是在類型後面!!與變量無關 C++中是在變量上 如: int *pWidth ,要區分開
&表示取地址 int* pX =&x //表示pX指向x
3將指針強制轉換爲整數類型
int x=10; int* pX,pY; pX = &x; pY =pX; * pY =20; uint y =(uint)pX; int* pD = (int*) Y;
4.指針類型之間的強制轉換
double* pDouble = (double*) pByte//pByte指針轉換爲double指針,不會獲得一個有意義的值. (合法的代碼)
5.void指針
int* pointerToInt; void* pointerToVoid; pointerToVoid = (void*)pointerToInt;//不多用,主要用於調用須要void*參數API函數
6.指針算術的運算 +、-、+=、-=、++、--
int* pInt=&int變量; pInt += 1 //不容許對void指針運算,注意byte與char其總字節數不是4的倍數,不能使用P+X*(sizeof(T))算法
7sizeof運算符
int x =sizeof(double) //返double類型佔用的字節數,注意不能用於計算類
8.結構指針:指針成員訪問運算符
struct MyStruct {public log X; public float F; } MyStruct* pStruct; //定義一個指針 MyStruct Struct = new MyStruct(); //初始化 pStruct = &Struct; //經過指針訪問結構成員 (*pStruct).X = 4; (*pStruct).Y =3.4f;
上述代碼改寫爲
pStruct->X = 4; pStruct->Y = 3.4f;
類成員指針
對象存儲在堆上,垃圾回收過程會變更,因此要使用fixed,語法以下
MyClass myObject =new MyClass(); Fixed (long* pX = &(myObject.X)) Fixed (float* pF = &(myObject.F)) { //程序 }
//類型相同時能夠放在一條fixed中 fixed(long* pX = &(myObject.X),pF = &(myObject.F))若是不一樣階段固定指針,能夠嵌套fixed塊
14.4指針示例
使用{0:X}格式輸出十六進制
下面爲自定義元素時
[FieldNameAttribute("SocialSecurityNumber")] public string SocialSecurityNumber { get{ //ect
一、AttributeUsage特性
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] //AllowMultiple = true 容許它屢次應用到同一項上
//Inherited = false若是該屬性能夠由派生類和重寫成員繼承,則爲 true;不然爲 false。 默認值爲 true public class LastModifiedAttribute : Attribute { public LastModifiedAttribute(string dateModified, string changes) { //程序 } }
[LastModified("14 Feb 2010", "IEnumerable interface implemented So Vector can now be treated as a collection")]
屬性
Type intType=typeof(int); //Type的屬性 name, fullname, Namepace命名空間, BaseType基類型 isClass是否爲類
方法
Type intType = typeof(int); MethodInfo[] methods = intType.GetMethods(); //取得該類型的法方 foreach (var test in methods) { Console.WriteLine(test); }
加載
Assembly theAssembly = Assembly.Load("VectorClass"); //查找程序集"VectorClass" Assembly theAssembly = Assembly.LoadFrom(@"c:\12\Some"); //在c:\12\Some查找程序集"VectorClass"
1,獲取程序集中定義的類型的詳細信息
ype[] types = theAssembly.GetTypes();
2獲取自定義特性的詳細信息
Attribute supportsAttribute = Attribute.GetCustomAttribute(theAssembly, typeof (SupportsWhatsNewAttribute)); //獲取程序集的特性
關於使用
Type T2 = typeof(TClass); var Mets = T2.GetMembers();//獲取全部公共成員(返回值是MemberInfo類型集合) foreach (var m in Mets) { if (m.Name=="Equals") { Console.WriteLine("【" + m.MemberType.ToString() + "】:" + m.Name); // m.MemberType 是成員類型 // m.DeclaringType;//獲取申明該成員的類 // m.ReflectedType;//獲取用於獲取 MemberInfo 的此實例的類對象。 } }
try { throw new Exception("ft"); } catch (OverflowException ex) { } catch (Exception ex) { } finally {
//程序完成後必定會執行的操做
}