之前有總結髮表過《近期開發項目中用到的編碼小技巧彙總說明》,雖沒有涉及什麼高大上的東西,但都是一些很實用的平時大家可能用到的知識,今天繼續分享一些小技巧,歡迎大家瞭解,不足之處,可以直接評論留言謝謝! 接上篇序號 6.解決當同一個類在不同的項目中(命名空間不同,但類的定義完全相同的情況)使用Bina ...
之前有總結髮表過《近期開發項目中用到的編碼小技巧彙總說明》,雖沒有涉及什麼高大上的東西,但都是一些很實用的平時大家可能用到的知識,今天繼續分享一些小技巧,歡迎大家瞭解,不足之處,可以直接評論留言謝謝!
接上篇序號
6.解決當同一個類在不同的項目中(命名空間不同,但類的定義完全相同的情況)使用BinaryFormatter進行序列化後再反序列化時出現找不到程式集的問題或反序列化的結果為null
原代碼:(DataSetSurrogate分別在API項目中,客戶端項目中都存在,類定義一樣但由於不在同一個項目,即使命名空間改成一樣仍然是會報錯的)
public static DataSet GZipBytesToDataSet(byte[] data) { byte[] buffer2 = data; BinaryFormatter ser = new BinaryFormatter(); var ms = new MemoryStream(buffer2); var obj = ser.Deserialize(ms); DataSetSurrogate dss = obj as DataSetSurrogate; return dss.ConvertToDataSet(); }
報錯原因是:序列化後的byte數組中包含了程式集的信息,故如果想要在另一個程式集中成功的反序列化,則需要動態替換反序列化中的類型對應的程式集信息,改進後的代碼:
先定義一個類型名稱替換序列化綁定器:
public class TypeNameConvertBinder : SerializationBinder { public TypeNameConvertBinder():base() { } public TypeNameConvertBinder(string oldNameSapce, string newNameSapce):this() { this.OldNameSapce = oldNameSapce; this.NewNameSapce = newNameSapce; } public string OldNameSapce { get; set; } public string NewNameSapce { get; set; } public override Type BindToType(string assemblyName, string typeName) { typeName = typeName.Replace(OldNameSapce, NewNameSapce); assemblyName = assemblyName.Replace(OldNameSapce, NewNameSapce); return Type.GetType(string.Format("{0}, {1}", typeName, assemblyName)); } }
然後序列化的時候直接給 BinaryFormatter設置Binder即可,代碼如下:
public static DataSet GZipBytesToDataSet(byte[] data) { byte[] buffer2 = data; BinaryFormatter ser = new BinaryFormatter(); ser.Binder = new TypeNameConvertBinder() { OldNameSapce = "WMS.Common", NewNameSapce = "Zuowj" }; var ms = new MemoryStream(buffer2); var obj = ser.Deserialize(ms); DataSetSurrogate dss = obj as DataSetSurrogate; return dss.ConvertToDataSet(); }
以上這樣就解決了序列化時因為程式集不相同而導致的反序列化失敗的問題。
7.控制台程式中實現輸入密碼遮罩功能,這個功能我是摘抄自網上的,還可以有優化空間
實現代碼如下:
static string ReadLineForPassword() { string input = null; while (true) { //存儲用戶輸入的按鍵,並且在輸入的位置不顯示字元 ConsoleKeyInfo ck = Console.ReadKey(true); //判斷用戶是否按下的Enter鍵 if (ck.Key != ConsoleKey.Enter) { if (ck.Key != ConsoleKey.Backspace) { //將用戶輸入的字元存入字元串中 input += ck.KeyChar.ToString(); //將用戶輸入的字元替換為* Console.Write("*"); } else { if (!string.IsNullOrEmpty(input) && input.Length >= 1) { input = input.Remove(input.Length - 1, 1); } //刪除錯誤的字元 Console.Write("\b \b"); } } else { Console.WriteLine(); break; } } return input; } //使用: string token = ReadLineForPassword();
這樣當用戶在控制臺上輸入密碼時則會以*號隱藏掉了。
好了今天就先分享到這裡,後續會繼續補充更新,敬請期待!