.Net下一個類型轉換神器

引言

類型轉換常常遇到,最經常使用的應該是string類型轉換爲其它基元類型,常見於http參數類型轉換。Convert靜態類的Convert.ChangeType()方法能夠把實現IConvertible接口的類型轉換爲其它也實現這個接口的類型,也等同於裏面的ToInt32()、ToDecimal()等方法的功能,但不支持轉換到這類型的可空類型,由於Nullable<>類型並無實現IConvertible這個接口;此外JavaScriptSerializer.ConvertToType()這個方法相對強大,支持轉換到Nullable<>類型、字符串到枚舉,也支持IDictionary<string,object>類型轉換爲對象,居於緣由,是爲了JavaScriptSerializer在反序列化JSON爲動態類型後,能把這些類型進行轉換爲常見類型,但JavaScriptSerializer.ConvertToType方法不能擴展。git

神器來了

名稱:

今天主角轉換器叫Converter,這是花費我幾天時間才琢磨出來。github

點再下載代碼(也要點個贊哦)web

功能:

今它支持基礎類型、decimal、guid和枚舉相互轉換以及這些類型的可空類型和數組類型相互轉換,支持字典和DynamicObject轉換爲對象以及字典和DynamicObject的數組轉換爲對象數組。json

擴展性:

能夠增長其它類型轉換,或修改某種轉換規則,也就是說轉換器是支持功能部分重寫和功能擴展的,功能移除也支持,好比想幹掉DynamicObject類型的轉換也能夠。api

神器使用方法

一、使用靜態方法,Converter.Cast(object value,Type targetType)或其泛型方法 :Converter.Cast<int?[]>(new[] {null, "2" }數組

二、實例化來調用,new Converter().Convert(new[] { null, "2" }, typeof(int?));服務器

 

Converter的擴展

擴展是靈魂,若是沒有擴展功能,這東東和JavaScriptSerializer.ConvertToType()有啥區別,Converter在擴展方面下了一翻功夫。轉換器裏包含多個轉換單元,這些單元能夠增長、刪除、替換和調整順序,自定義的單元,能夠從已有單元派生,也能夠完整實現,而後插入到轉換器的轉換單元管理器中,轉換器就升級了。而轉換單元自己也能調用轉換器來轉換,這就造成一種可擴展的遞歸。websocket

關係代碼以下:socket

 /// <summary>
        /// 類型轉換
        /// </summary>
        public Converter()
        {
            this.Items = new ContertItems()
                .AddLast<NoConvert>()
                .AddLast<NullConvert>()
                .AddLast<PrimitiveContert>()
                .AddLast<NullableConvert>()
                .AddLast<DictionaryConvert>()
                .AddLast<ArrayConvert>()
                .AddLast<DynamicObjectConvert>();
        }
轉換器由轉換單元組成
 /// <summary>
    /// 定義類型轉換單元
    /// </summary>
    public interface IConvert
    {
        /// <summary>
        /// 將value轉換爲目標類型
        /// 並將轉換所得的值放到result
        /// 若是不支持轉換,則返回false
        /// </summary>
        /// <param name="converter">轉換器實例</param>
        /// <param name="value">要轉換的值</param>
        /// <param name="targetType">轉換的目標類型</param>
        /// <param name="result">轉換結果</param>
        /// <returns>若是不支持轉換,則返回false</returns>
        bool Convert(Converter converter, object value, Type targetType, out object result);
    }
轉換單元能夠調用轉換器


刪除轉換單元:

var converter = new Converter();
converter.Items.Remove<DynamicObjectConvert>();

增長轉換單元:ide

編寫一個單元,實現IConvert接口,好比 class JObjectConvert:IConvert{},而後就能夠把這個轉換單元添加到轉換器實例中,

var converter = new Converter();
converter.Items.AddFrist<JObjectConvert>();

轉換單元重寫:

好比從string轉換爲decimal類時,要求5位小數,咱們能夠寫一個單元,class MyPrimitiveContert:PrimitiveContert{},而後改寫裏面的Convert方法,再把MyPrimitiveContert替換轉換器裏的PrimitiveContert單元

var converter = new Converter();
converter.Items.Replace<PrimitiveContert, MyPrimitiveContert>();

後記

之因此寫這個東西,是由於個人NetworkSocket組件裏websocket部分很須要一個靈活的類型轉換器,客戶端發送{api:"login",parameters:[{account:"admin",password:"123456"}]}這樣結構的Json給服務器,服務要解析這個json而後反射執行Login(Userinfo user)這個方法。

這裏parameters數組裏內容的類型是根據api的名稱而定的,而要解析到api的內容,又要知道整個json的結構,造成蛋和雞。只有將json解析爲動態類型,才能知足要求,而JavaScriptSerializer反序列化爲動態類型時,其實是json對象轉換爲字典,json數組轉換爲ArrayList,其它基本類型差很少一一對應,枚舉類型看狀況;若是使用Json.Net解析,json對象轉換爲JObject動態類型,json數組轉換爲JArray,一些基本類型通常會對應JValue。

當把序列化和反序列化抽象或定義爲接口的時候,JavaScriptSerializer.Converter方法就無力了,它無法轉換JObject這些類型,也沒有擴展的入口點,還有就是在.net core上也用不了。而Converter只須要添加一個單元轉換單元,用來實現Json.Net裏面幾個動態類型轉換爲Api參數的類型,就能夠達到完美的轉換效果。

相關文章
相關標籤/搜索