Time of Update: 2018-12-07
FormatterService(在System.Runtime.Serialization命名空間內)的GetUninitializedObject方法是.NET還原序列化中CLR初始化對象用到的方法(眾所周知,還原序列化中對象的建構函式是不被調用的)。這個方法我們也可以直接使用來達到相同的效果。 如下代碼:using System;using System.Runtime.Serialization; namespace Mgen{ class a {
Time of Update: 2018-12-07
當使用Serializable特性,如果類有更新(但有要求和以前序列化的類對象保持相容),可以使用OptionalField特性來標記新加的欄位。至於Serializable特性在類繼承上,問題不會很大,只要父類被標記Serializable特性,那麼子類就可以序列化父類的內容。 而對於ISerializable介面,由於序列化和還原序列化都得自己動手,那麼處理類更新和繼承問題就會稍複雜一些。 比如版本更新,我們可以在SerializationInfo中加入自己的版本資訊,在還原序列化中再根據不
Time of Update: 2018-12-07
StreamingContext類型出現在諸多序列化的方法中。ISerializable的GetObjectData和特殊的建構函式(用於還原序列化)。還有[OnDeserialized], [OnDeserializing], [OnSerialized],
Time of Update: 2018-12-07
全部版本的原始碼下載: 注意:此為微軟SkyDrive存檔,請用瀏覽器直接下載,用某些下載工具可能無法下載 版本更新歷史:2.0增加了對擴充表單樣式(GWL_EXSTYLE標誌)的更好支援支援:增加WindowStylesEx枚舉定義。 1.0簡單的GetWindowLongPtr和SetWindowLongPtr封裝。具體介紹可以參考:.NET(C#) 平台叫用:不依賴平台的GetWindowLongPtr和SetWindowLongPtr API
Time of Update: 2018-12-07
System.Diagnostics.Switch類的Value和SwitchSettings屬性是protected修飾符,並且是可以設定的。Value是字串類型,SwitchSetting是int類型。Switch類的值是Value屬性,當值被設定後,Switch會嘗試將Value字串轉換成SwitchSetting的數字。如果無法成功轉換,異常將會被拋出。 當自訂Switch類時,可以改寫OnValueChanged和OnSwitchSettingChanged方法來自訂Value屬性和S
Time of Update: 2018-12-07
對於API的EnumWindows,第一個參數WNDENUMPROC是一個函數指標類型(EnumWindowsProc),HWND代表表單的控制代碼。第二個LPARAM代表EnumWindows的第二個參數,即傳入回呼函數的使用者自訂對象(參數)。 EnumWindows只能擷取一個表單的控制代碼,因此用GetWindowText返回視窗的標題。 代碼://函數指標類型delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr
Time of Update: 2018-12-07
研究一下正則RegexOptions枚舉的三個針對匹配行的區別,對應None,SingleLine(單行)和Multiline(多行)枚舉值。 結論是:None:(.)匹配任何字元除了\n。^和$不起作用。 Singleline:(.)匹配任何字元。^和$匹配整個字串 Multiline:(.)匹配任何字元除了\n。^和$匹配每行的開頭和結尾。 另外貌似目前.NET的正則對\A和\Z支援的不是很好。下面測試代碼:(注意由於輸出字元中有分行符號,因此用ASCII碼作輸出)//+ using
Time of Update: 2018-12-07
當不使用SMTP的25連接埠號碼發送郵件,某些低許可權執行環境可以會拋出異常,最好還是在執行操作前進行許可權的檢查。 SMTP在.NET中對應的許可權是:SmtpPermission類型(還有聲明式的SmtpPermissionAttribute特性,他們都在System.Net.Mail命名空間下)。他的Access屬性控制許可權的內容。對應一個SmtpAccess枚舉。有3個值:None(沒有),Connect(串連預設連接埠25),ConnectToUnrestrictedPort(串連任
Time of Update: 2018-12-07
如果你對Windows存取控制不瞭解的話,建議先看這篇文章: 淺談Windows存取控制在.NET(C#)中的實現(ACE, SD, DACL, SACL) 我們知道在系統存取控制清單(SACL)中,ACE是審核規則,.NET中System.Security.AccessControl命名空間內封裝了審核規則(Audit
Time of Update: 2018-12-07
目錄1. 單個程式集配置重新導向2. 發行者策略程式集3. 開發測試中頻繁版本更新 返回目錄1. 單個程式集配置重新導向當單個依賴程式集,比如A,依賴程式集B,比如使用B的1.0版本。現在B從1.0升級到了2.0。那麼此時可以在程式集A中手動重新導向B的版本,這樣在程式集A運行後會自動使用更新的2.0版本的程式集B。 程式集的版本重新導向須寫在程式集自己的設定檔中(App.config)。在<configuration> – <runtime> –
Time of Update: 2018-12-07
我們知道,AppDomain.ProcessExit能監視當前進程的退出,而Process.Exited事件只能監視其他進程的退出。而且如果進程被強制結束AppDomain.ProcessExit不會發生的。綜上事實,我們可以用兩個進程互相監視另一個進程的Process.Exited事件來,然後如果一個進程被結束,另一個進程會重新開啟這個程式。 比如樣本中兩個程式,mgen_p1,和mgen_p2。一個程式結束後,另一個程式會馬上重新運行被結束的程式。當然如果兩個程式同時被結束,那麼他們會被徹底
Time of Update: 2018-12-07
HTTP請求包頭資訊中有一個Range屬性可以指定索取部分HTTP請求的檔案。在.NET中則通過HttpWebRequest.AddRange方法來定義資料的範圍。當添加了Range屬性的HTTP請求發送後,如果伺服器支援該請求,也就是說支援部分資料提取(也是我們常說到的支援斷點續傳的下載,所謂斷點續傳的下載就是用一個Range屬性來指定沒有下載到的範圍),那麼伺服器會返回Partial Content狀態值。否則會返回OK狀態值(200代碼)。注意如果伺服器支援Range但是HTTP
Time of Update: 2018-12-07
和for/foreach中發生異常的表現一樣,Parallel迴圈中的任何異常都會使整個迴圈終止,注意由於整個迴圈是分塊同時進行的,因此整個迴圈不會立即終止(如果有一個線程進行中長時間工作的話,而且是發生在CancellationToken的ThrowIfCancellationRequested方法之後)。 代碼:try{ Parallel.For(0, 5, (i) => { throw new Exception("異常。迭代數字:" + i); })
Time of Update: 2018-12-07
首先當Break被調用後,迴圈中當前調用Break的執行後的迭代就沒有必要去執行了,由於並存執行打亂了執行順序,所以這個時候很可能某些不需要執行的迭代已經執行完了,這個沒辦法(也沒必要)去取消它,當然調用Break後沒有必要執行且沒有開始執行的迭代最終不會被執行。 上面只討論了“已經執行完”和“沒有執行的狀況”,對於正在執行的卻沒有必要執行的迭代,同樣沒辦法將他停止,此時ParallelLoopState.LowestBreakIteration(類型是long?,預設是null)則會成為最小的
Time of Update: 2018-12-07
更新:在C# 5.0後,await所產生的取消Task異常會直街拋出異常。比如下面的代碼,在C# 5.0/.NET 4.5中等效於:var src = new CancellationTokenSource();src.CancelAfter(100);try{ await Task.Factory.StartNew(() => { Thread.Sleep(1000); src.Token.ThrowIfCancellationRequested(
Time of Update: 2018-12-07
當你在一個Task執行中拋出異常,比如:Task.Factory.StartNew(() =>{ throw new Exception();});運行該方法,沒有任何異常拋出。 事實上此時Task的異常處於未覺察狀態,這個未覺察狀態的異常會在記憶體回收時終結器執行線程中被拋出。為了誘發這個異常,我們可以通過GC.Collect來強制記憶體回收從而引發終結器處理線程,此時Task的未覺察異常會被拋出。//在Task中拋出異常Task.Factory.StartNew(() =>
Time of Update: 2018-12-07
這個特性太碉堡了,很像WPF中的資料繫結,當然本質就是Visual Studio在調試時利用反射擷取對象的值。 建構函式中的屬性值(就是{}中的內容)不僅僅可以是簡單的屬性值。還可以是索引器,而且這一切可以嵌套。(DebuggerDisplay特性(DebuggerDisplayAttribute類型)在System.Diagnostics命名空間內) 來定義一個有DebuggerDisplay的類:
Time of Update: 2018-12-07
在C/C++中,整數變數的膚質是從來不進行越界檢查的,於是你可以給一個int變數成功賦予比INT_MAX(C/C++中定義的int的最大值)都大的數字,或者給不帶正負號的整數賦予一個負數值,結果就是值會被暴力塞到對應變數的空間內,因此二進位中多餘的高位可能會被剪掉。 事實上C語言標準並沒有強制這樣做,但是C語言的具體執行通常都會這樣的。 可以參考C語言標準4.7 Integral
Time of Update: 2018-12-07
我們常見到的位域標誌定義都是基於正數的,不過其實也可以定義成基於負數的,工作起來則和正數標誌位域一樣。 比如定義一個8位的位域,提供兩個選項分別是最高位和最低位為1。然後分別以byte和sbyte作為枚舉背後資料類型,則枚舉應該這樣聲明:[Flags]enum a : byte{ //128的原碼為:10000000 High = 128, Low = 1} [Flags]enum b : sbyte{ //-128的補碼為:10000000 High = -128
Time of Update: 2018-12-07
目錄Task.Unwrap基本使用 Task.Factory.StartNew和Task.Run的Unwrap操作 使用案例:LINQ中的async Lambda 返回目錄 Task.Unwrap基本使用這個擴充方法定義在TaskExtensions類型中,命名空間在System.Threading.Tasks。Unwrap會把嵌套的Task<Task>或者Task<Task<T>>的結果提取出來。 就像這樣,不用Unwrap的話:static void