標題 | 狀態 | 內容 | ||||||||||||||||||||||||||
NET應用程序是如何執行的? |
http://www.cnblogs.com/kingmoon/archive/2012/07/16/2594459.htmlhtml |
|||||||||||||||||||||||||||
從彙編入手,探究泛型的性能問題 |
|
|||||||||||||||||||||||||||
彙編及IL | 從這裏咱們能夠看到,CLR爲引用類型(string/object/Program)生成共享的機器碼,它們都實際上在調用一個GenericMethod<System.__Canon>所生成的代碼。而對於每一個不一樣的值類型(int/DateTime/double),CLR則會爲每種類型各生成一份 數據庫 http://www.cnblogs.com/JeffreyZhao/archive/2009/06/03/my-view-of-il-2-il-shows-little-about-clr.htmlc# |
|||||||||||||||||||||||||||
JIT | JIT Compiler(Just-in-time Compiler) 即時編譯 | |||||||||||||||||||||||||||
。NET和C#各個版本的變遷 | 已讀 | CLR是公共語言運行庫(Common Language Runtime) http://www.cnblogs.com/lufangtao/archive/2012/06/07/2539915.html設計模式
CLR 徹底介紹 深刻探討 IDisposable https://msdn.microsoft.com/zh-cn/magazine/cc163392.aspx
Net 版本和C#對應關係數組 .Net各版本差異 參考安全 http://blog.csdn.net/xjc1278003262/article/details/8605738?utm_source=tuicool服務器
C#各版本差異
|
||||||||||||||||||||||||||
HttpContext請求上下文對象 | ||||||||||||||||||||||||||||
值類型和引用類型的區別 |
http://www.cnblogs.com/Autumoon/archive/2008/08/18/1270685.html 全部值類型都繼承自System.ValueType,可是ValueType沒有附加System.Object包含以外其它任何方法,不過它卻是改寫了Equals和GetHashCode兩個方法。引用類型變量的Equals比較的是兩者的引用地址而不是內部的值,值類型變量的Equals方法比較的是兩者的值而不是……哦對了,值類型壓根兒沒有引用地址; |
|||||||||||||||||||||||||||
c# ==和equals的區別 | http://kb.cnblogs.com/page/206353/ http://stackoverflow.com/questions/21273890/what-is-the-difference-between-and-equals-for-primitives-in-c
對於值類型 對於不一樣的類型會強制轉換成前面的類型。若是如short -》int 行 int=》short 不行
對於引用類型 ==比較的是引用地址是否相同(即棧中的內容是否相同),equal比較的是2個變量師傅是對同一個對象的引用,即堆中的內容是否相同。
值類型 類型不一樣的時候會調用不一樣的equal
Equals和GetHashcode http://blog.csdn.net/afgasdg/article/details/6889383
http://www.cnblogs.com/lwzz/archive/2012/02/26/2361843.html
ReferenceEquals是Object的靜態方法,用於比較兩個引用類型的對象是不是對於同一個對象的引用。
C#參考 :ReferenceEquals, == , Equals http://www.cnblogs.com/Dlonghow/archive/2008/08/04/1259732.html
默認狀況下,對於引用類型,該方法對比的時引用的地址,對於值類型,對比的是值的二進制描述是否相同。100.0與100雖然都是100,可是它們的二進制分佈是不同的。
五、將元素放入集合的流程圖:
|
|||||||||||||||||||||||||||
內存分配 |
http://www.cnblogs.com/aaa6818162/p/4644505.html 從內存分配看函數參數傳遞問題 http://blog.csdn.net/fmoonstar/article/details/6827030變量、參數和內存分配 http://www.cnblogs.com/IOS-Developer/p/4117618.html
對於一個進程的內存空間而言,能夠在邏輯上分紅3個部份:代碼區,靜態數據區和動態數據區。動態數據區通常就是「堆棧」。「棧(stack)」和「堆(heap)」是兩種不一樣的動態數據區,棧是一種線性結構,堆是一種鏈式結構。進程的每一個線程都有私有的「棧」,因此每一個線程雖然代碼同樣,但本地變量的數據都是互不干擾。一個堆棧能夠經過「基地址」和「棧頂」地址來描述。全局變量和靜態變量分配在靜態數據區,本地變量分配在動態數據區,即堆棧中。程序經過堆棧的基地址和偏移量來訪問本地變量。 |
|||||||||||||||||||||||||||
字符串的駐留(String Interning) |
http://www.cnblogs.com/artech/archive/2007/03/04/663728.aspx 於String是咱們作到頻率最高的一種類型,CLR考慮性能的提高和內存節約上,對於相同的字符串,通常不會爲他們分別分配內存塊,相反地,他們會共享一塊內存。CLR實際上採用這個的機制來實現的:CLR內部維護着一塊特殊的數據結構——咱們能夠把它當作是一個Hash table,這個Hash table維護者大部分建立的string(我這裏沒有說所有,由於有特例)。這個Hash table的Key對應的相應的string自己,而Value則是分配給這個string的內存塊的引用。當CLR初始化的時候建立這個Hash table。通常地,在程序運行過程當中,若是須要的建立一個string,CLR會根據這個string的Hash Code試着在Hash table中找這個相同的string,若是找到,則直接把找到的string的地址賦給相應的變量,若是沒有則在託管堆中建立一個string,CLR會先在managed heap中建立該strng,並在Hash table中建立一個Key-Value Pair——Key爲這個string自己,Value位這個新建立的string的內存地址,這個地址最重被賦給響應的變量
深刻理解string和如何高效地使用string http://www.cnblogs.com/artech/archive/2007/05/06/737130.html |
|||||||||||||||||||||||||||
C#中,String和string的區別 |
C#中,字符串的聲明,你使用String仍是string?
也能夠這樣理解:string是C#中字符串類型String的反射,一種簡化的書寫方式,就像int對應於Int32同樣,兩者在C#中可通用。
|
|||||||||||||||||||||||||||
http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 咱們明明就是改變了String型的變量s的,爲何說是沒有改變呢? 其實這是一種欺騙,JVM是這樣解析這段代碼的:首先建立對象s,賦予一個abcd,而後再建立一個新的對象s用來 執行第二行代碼,也就是說咱們以前對象s並無變化,因此咱們說String類型是不可改變的對象了,因爲這種機制,每當用String操做字符串時,其實是在不斷的建立新的對象,而原來的對象就會變爲垃圾被GC回收掉,可想而知這樣執行效率會有多底。 而StringBuffer與StringBuilder就不同了,他們是字符串變量,是可改變的對象,每當咱們用它們對字符串作操做時,其實是在一個對象上操做的,這樣就不會像String同樣建立一些而外的對象進行操做了,固然速度就快了。
一個特殊的例子:
1 String str = 「This is only a」 + 「 simple」 + 「 test」;
3 StringBuffer builder = new StringBuilder(「This is only a」).append(「 simple」).append(「 test」); 對於三者使用的總結: 1.若是要操做少許的數據用 = String 2.單線程操做字符串緩衝區 下操做大量數據 = StringBuilder 3.多線程操做字符串緩衝區 下操做大量數據 = StringBuffer |
||||||||||||||||||||||||||||
參數的類型 | 實參和形參:形參就是函數定義時候用的,實參是在函數調用時候用的。
1. 好比你定義一個函數void add(int a, int b),這裏的a和b就是形參。
|
|||||||||||||||||||||||||||
變量和參數 | http://www.cnblogs.com/lanxiazhi/archive/2009/03/19/1417161.html 局部變量是指在函數型成員如方法、屬性、索引器中聲明的變量 聲明時指定了static修飾符的字段就是靜態變量 C#中一共有四種類型的參數:值參數,引用參數,輸出參數,參數數組。
|
|||||||||||||||||||||||||||
C# const, readonly, static readonly | http://www.cnblogs.com/qingxia/archive/2011/02/10/1950741.html
Const 定義的是靜態常在對象初始化的時候賦值.之後不能改變它的值.屬於編譯時常量。不能用new初始化。 Readonly 是隻讀變量.屬於運行時變量.能夠在類constructor裏改變它的值.不能做用於局部變量。 const 和 static 不能在一塊兒用,它已是靜態的了。 咱們都知道,const和static readonly的確很是像:經過類名而不是對象名進行訪問,在程式中只讀等等。在多數狀況下能混用。 而static readonly,在程式中只讀, 不過它是在運行時計算出其值的,因此還能經過靜態構造函數來對它賦值, readonly只能用來修飾類的field,不能修飾局部變量,也不能修飾property等其餘類成員 |
|||||||||||||||||||||||||||
委託 事件 什麼是委託? 委託和事件的關係? |
http://www.cnblogs.com/chengzish/p/4559268.html http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx 委託 是存放方法的指針的清單,也就是裝方法的容器 事件是委託對象,事件自身實現了對委託對象的保護 因此event關鍵字本質就是作了兩個事情,從而實現對委託對象的保護: 1,建立了一個對應的Private委託對象 2,而後添加Add和Remove方法訪問、操做這個Private委託對象。 Observer設計模式是爲了定義對象間的一種一對多的依賴關係,以便於當一個對象的狀態改變時, 其餘依賴於它的對象會被自動告知並更新。Observer模式是一種鬆耦合的設計模式。
![]() <SPAN style="FONT-SIZE: 13px">using System; using System.Collections.Generic; using System.Text; namespace Delegate { // 熱水器 public class Heater { private int temperature; public delegate void BoilHandler(int param); //聲明委託 public event BoilHandler BoilEvent; //聲明事件 // 燒水 public void BoilWater() { for (int i = 0; i <= 100; i++) { temperature = i; if (temperature > 95) { if (BoilEvent != null) { //若是有對象註冊 BoilEvent(temperature); //調用全部註冊對象的方法 } } } } } // 警報器 public class Alarm { public void MakeAlert(int param) { Console.WriteLine("Alarm:嘀嘀嘀,水已經 {0} 度了:", param); } } // 顯示器 public class Display { public static void ShowMsg(int param) { //靜態方法 Console.WriteLine("Display:水快燒開了,當前溫度:{0}度。", param); } } class Program { static void Main() { Heater heater = new Heater(); Alarm alarm = new Alarm(); heater.BoilEvent += alarm.MakeAlert; //註冊方法 heater.BoilEvent += (new Alarm()).MakeAlert; //給匿名對象註冊方法 heater.BoilEvent += Display.ShowMsg; //註冊靜態方法 heater.BoilWater(); //燒水,會自動調用註冊過對象的方法 } } } 輸出爲: Alarm:嘀嘀嘀,水已經 96 度了: Alarm:嘀嘀嘀,水已經 96 度了: Display:水快燒開了,當前溫度:96度。 // 省略... </SPAN>
|
|||||||||||||||||||||||||||
多線程 static 單例 |
線程上下文切換的性能損耗測試 http://www.cnblogs.com/EthanCai/p/3705834.html
static 在多線程的狀況 Static與線程安全 http://yinlei555.iteye.com/blog/707986靜態方法是否有線程安全問題?要看在靜態方法中是否使用了靜態成員。
![]() c#建立帶參數的線程 1、無參數線程的建立 Thread thread = new Thread(new ThreadStart(getpic)); thread.Start(); private void showmessage() { Console.WriteLine("hello world"); } 2、帶一個參數的線程 使用ParameterizedThreadStart,調用 System.Threading.Thread.Start(System.Object) 重載方法時將包含數據的對象傳遞給線程。 注意傳遞的參數只能是object類型,不過能夠進行強制類型轉換。 Thread thread = new Thread(new ParameterizedThreadStart(showmessage)); string o = "hello"; thread.Start((object)o); private static void showmessage(object message) { string temp = (string)message; Console.WriteLine(message); } 3、帶兩個及以上參數的線程 這時候能夠將線程執行的方法和參數都封裝到一個類裏邊,經過實例化該類,方法就能夠調用屬性來盡享傳遞參數。 例如以下程序,想傳入兩個string變量,而後打印輸出。 public class ThreadTest { private string str1; private string str2; public ThreadTest(string a, string b) { str1 = a; str2 = b; } public void ThreadProc() { Console.WriteLine(str1 + str2); } } public class Example { public static void Main() { ThreadTest tt = new ThreadTest("hello ", "world"); Thread thread = new Thread(new ThreadStart(tt.ThreadProc)); thread.Start(); } }
http://www.cnblogs.com/aaa6818162/p/4516940.html ![]() /// <summary> /// 定義公有方法提供一個全局訪問點,同時你也能夠定義公有屬性來提供全局訪問點 /// </summary> /// <returns></returns> public static Singleton GetInstance() { // 當第一個線程運行到這裏時,此時會對locker對象 "加鎖", // 當第二個線程運行該方法時,首先檢測到locker對象爲"加鎖"狀態,該線程就會掛起等待第一個線程解鎖 // lock語句運行完以後(即線程運行完以後)會對該對象"解鎖" // 雙重鎖定只須要一句判斷就能夠了 if (uniqueInstance == null) { lock (locker) { // 若是類的實例不存在則建立,不然直接返回 if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; }
|
|||||||||||||||||||||||||||
Dispose(); .Clear(); = null | DataTable的 .Dispose(); .Clear(); = null; 三個有何區別,?http://zhidao.baidu.com/link?url=HE1FqLFeui856OhD7i3n4aKEicDJh42GaRm0EuLGvJC9xPIwQCmWM99D_iEmv3d035-8Td8hcIcJD-qIgXnz8_ | |||||||||||||||||||||||||||
深拷貝淺拷貝 | ICloneable 淺拷貝就好比像引用類型,而深拷貝就好比值類型。 淺拷貝是指源對象與拷貝對象共用一份實體,僅僅是引用的變量不一樣(名稱不一樣)。對其中任何一個對象的改動都會影響另一個對象。舉個例子,一我的一開始叫張三,後來更名叫李四了, 但是仍是同一我的,無論是張三缺胳膊少腿仍是李四缺胳膊少腿,都是這我的倒黴。 深拷貝是指源對象與拷貝對象互相獨立,其中任何一個對象的改動都不會對另一個對象形成影響。舉個例子,一我的名叫張三,後來用他克隆(假設法律容許)了另一我的, 叫李四,無論是張三缺胳膊少腿仍是李四缺胳膊少腿都不會影響另一我的。比較典型的就是Value(值)對象,如預約義類型Int32,Double,以及結構(struct),枚舉(Enum)等。 |
|||||||||||||||||||||||||||
Lambda表達式詳解 | http://www.cnblogs.com/aaa6818162/p/4677140.html //傳入參數類型 Action<string> action = s => { Console.WriteLine(s); }; //傳入參數類型 返回參數類型 Func<int,int> gwl = p => { return p + 10; };
|
|||||||||||||||||||||||||||
c#擴展方法 | ||||||||||||||||||||||||||||
async and await 簡單的入門 | http://www.cnblogs.com/LoveJenny/archive/2011/11/01/2230933.html http://blog.csdn.net/tianmuxia/article/details/17675681 http://www.cnblogs.com/jesse2013/p/async-and-await.html 線程的建立是比較佔用資源的一件事情,.NET 爲咱們提供了線程池來幫助咱們建立和管理線程。Task是默認會直接使用線程池,可是Thread不會。若是咱們不使用Task,又想用線程池的話,可使用ThreadPool類。
await並非針對於async的方法,而是針對async方法所返回給咱們的Task,這也是爲何全部的async方法都必須返回給咱們Task。因此咱們一樣能夠在Task前面也加上await關鍵字,這樣作其實是告訴編譯器我須要等這個Task的返回值或者等這個Task執行完畢以後才能繼續往下走。 |
|||||||||||||||||||||||||||
迭代器 | http://www.cnblogs.com/yangecnu/archive/2012/03/17/2402432.html foreach編譯來調用GetEnumerator和MoveNext方法以及Current屬性 http://dotnet.9sssd.com/csbase/art/794 考慮這樣一種狀況。假設數組是靠鏈表實現的(其實是線性表,可是咱們這裏假設)。 |
|||||||||||||||||||||||||||
for和foreach | http://m.blog.csdn.net/blog/sansan52048/9159941
![]() 1 在foreach循環中,迭代集合collectionObject的過程以下: 2 (1)調用collectionObject.GetEnumerator(),返回一個IEnumerator引用。這個方法能夠經過IEnumerable接口的實現代碼來得到。但這是可選的。 3 (2)調用返回的IEnumerator接口的MoveNext()方法。 4 (3)若是MoveNext()方法返回true,就使用IEnumerator接口的Current屬性獲取對象的一個引用,用於foreach循環。 5 (4)重複前面兩步,直到MoveNext()方法返回false爲止,此時循環中止。 6 7 8 替代foreach實現: 9 foreach (XXX a in b){ 10 ... 11 } 12 13 等同於 14 15 XXX a; 16 IEnumerator ie = (IEnumable)b.GetEnumerator(); 17 while (ie.MoveNext) { 18 a = (XXX)ie.Current; 19 ... 20 }
![]() foreach是取只讀的,在取的時候數據隊列不能變(包括修改,刪除,添加等)。要避免這個問題,就應該使用for循環。 IList<Person> iList = new List<Person>(); iList.Add( new Person("david",13)); iList.Add(new Person("bob", 11)); iList.Add(new Person("justin",12)); // 用linq從新排序 var textList = (from c in iList orderby c.age select c); int iPerson =0; foreach (Person p in textList) { // 這時候在immediate Window裏面輸入iList.RemoveAt(2),程序會拋出異常 Console.WriteLine(p.name + ":" + p.age); iList[iPerson] = p; // 排序後修改原來的隊列!!! iPerson++; } for (int ii = 0; ii < iList.Count; ii++) { // 這時候在immediate Window裏面輸入iList.RemoveAt(2),程序不會拋出異常 Console.WriteLine(iList[ii].name); }
|
|||||||||||||||||||||||||||
狀態機 | http://www.cnblogs.com/TianFang/archive/2007/12/27/1017665.html | |||||||||||||||||||||||||||
線程靜態字段 System.ThreadStaticAttribute | http://www.cnblogs.com/SkylineSoft/articles/1726232.html ThreadStaticAttribute 的做用是告訴CLR,它標記的靜態字段的存取是依賴當前線程,而獨立於其餘線程的。 例如: class MyClass{ MyClass 中的threadvalue就是一個線程靜態字段 。 若是一個程序中同時有多個線程同時訪問這個字段,則每一個線程訪問的都是獨立的threadvalue 。例如線程1設置它爲」hello」,而後線程2設置它爲」world」,最後線程1讀取它的時候,獲得的是」hello」。 基於這個,線程靜態字段有如下特徵:
可是,使用線程靜態字段要注意:
若是你知道 System.Runtime.Remoting.Messaging.Context (如下簡稱MContext)
|
|||||||||||||||||||||||||||
List<T>傳值 |
![]() [__DynamicallyInvokable] public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) { if (source == null) throw Error.ArgumentNull("source"); return new List<TSource>(source); } /// <summary> /// 初始化 <see cref="T:System.Collections.Generic.List`1"/> 類的新實例,該實例包含從指定集合複製的元素而且具備足夠的容量來容納所複製的元素。 /// </summary> /// <param name="collection">一個集合,其元素被複制到新列表中。</param><exception cref="T:System.ArgumentNullException"><paramref name="collection"/> 爲 null。</exception> [__DynamicallyInvokable] public List(IEnumerable<T> collection) { if (collection == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection); ICollection<T> collection1 = collection as ICollection<T>; if (collection1 != null) { int count = collection1.Count; if (count == 0) { this._items = List<T>._emptyArray; } else { this._items = new T[count]; collection1.CopyTo(this._items, 0); this._size = count; } } else { this._size = 0; this._items = List<T>._emptyArray; foreach (T obj in collection) this.Add(obj); } }
[TestMethod] public void TestMethod2() { IList<PostData> list = new List<PostData>(); list.Add(new PostData() { id = "1111", startId = "11" }); list.Add(new PostData() { id = "2222", startId = "11" }); file(list); Assert.IsTrue(list.Count==1);//2 } public void file(IList<PostData> list) { list = list.Where(p => p.id == "1111").ToList(); }
|
|||||||||||||||||||||||||||
終結器 | http://blog.csdn.net/fxqcn/article/details/6717426 | |||||||||||||||||||||||||||
託管代碼和非託管代碼 | http://www.cnblogs.com/muzhiye/archive/2012/02/23/2365556.html net託管代碼是運行在.NET FRAMEWORK上的,相似於JAVA虛擬機 |
|||||||||||||||||||||||||||
C#編譯器 JIT編譯器 | 從C#的源代碼到機器代碼,中間要通過兩個編譯器。一個就是把C#源代碼編譯成託管模塊的C#編譯器。另外一個就是做爲CLR一個組件的JIT編譯器。每通過一次編譯,程序的語言就更低級一步。 C#編譯器生成的是IL語言和元數據
C#編譯器是用來生成包含IL和元數據的模塊的,一旦編譯完成,東西基本就是定下來了的。而JIT編譯器會根據元數據和狀況來作一些改變。好比泛型中的類型參數的填入和生成相應的機器代碼,都是JIT編譯器作的,而不是C#編譯器。C#編譯器的工做就是生成相應的IL和元數據告訴JIT這是一個泛型類型,有類型實參。編譯好的程序集,放在那裏不動,程序集裏的IL和元數據固然不會發生變化。而同一個程序集,在不一樣CLR版本中的行爲和性能就有可能不一樣,也是同樣的道理。
|
|||||||||||||||||||||||||||
CLR VIA | http://www.cnblogs.com/janes/category/308324.html | |||||||||||||||||||||||||||
.Net 託管模塊與程序集的關係 |
http://blog.csdn.net/kmguo/article/details/17055065 | |||||||||||||||||||||||||||
.NET概念:.NET程序編譯和運行 |
http://blog.csdn.net/yysyangyangyangshan/article/details/7306346
|
|||||||||||||||||||||||||||
淺談.NET中泛型的基本原理 | http://www.cnblogs.com/DebugLZQ/archive/2012/09/03/2669383.html
|
|||||||||||||||||||||||||||
NET PDB文件究竟是什麼? | http://www.cnblogs.com/imjustice/archive/2013/06/07/note_about_dot_net_pdb_file.html 這個文件會在咱們調試的時候被使用到,這個東西能夠理解爲調試的時候應用程序和源文件之間的一個橋樑。正是歸功於這個文件,咱們才能在debug的時候看到程序當前執行相對應的代碼和監視到一些變量 主要遠程調試能夠用 |
|||||||||||||||||||||||||||
彙編 | ||||||||||||||||||||||||||||
類型參數 | 尖括號中的T是不肯定的數據類型,叫作類型參數,通常規定以字母T開頭,能夠是TKey, TValue均可以。而調用時指定的具體類型叫作類型實參。 |
|||||||||||||||||||||||||||
開放類型與封閉類型 | 開放類型:具備泛型參數的類型是開放類型,如List<T>,CLR不容許構造開放類型的實例; 封閉類型:在實際調用代碼時,若是全部類型實參都已經指定了實際數據類型,如List<string>,則該類型爲封閉類型。CLR容許構造封閉類型的實例。 |
|||||||||||||||||||||||||||
正確實現 IDisposable 接口 |
http://www.cnblogs.com/xlshcn/archive/2007/01/16/idisposable.html 在.NET的對象中實際上有兩個用於釋放資源的函數:Dispose和Finalize。Finalize的目的是用於釋放非託管的資源,而Dispose是用於釋放全部資源,包括託管的和非託管的。 Dispose和Finalize。Finalize的目的是用於釋放非託管的資源,而Dispose是用於釋放全部資源,包括託管的和非託管的。 |
|||||||||||||||||||||||||||
C# 託管資源和非託管資源 | 那麼對於非託管的資源,這裏再重申一下,就是Stream,數據庫的鏈接,GDI+的相關對象,還有Com對象等等這些資源 最多見的一類非託管資源就是包裝操做系統資源的對象,例如文件,窗口或網絡鏈接,對於這類資源雖然垃圾回收器能夠跟蹤封裝非託管資源的對象的生存期,但它不瞭解具體如何清理這些資源。還好.net Framework提供了Finalize()方法,它容許在垃圾回收器回收該類資源時,適當的清理非託管資源。若是在MSDN Library 中搜索Finalize將會發現不少相似的主題,這裏列舉幾種常見的非託管資源:ApplicationContext,Brush,Component,ComponentDesigner,Container, Context,Cursor,FileStream,Font,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader,Pen,Regex,Socket,StreamWriter,Timer,Tooltip 等等資源。 |