之前的一個(gè) 封裝讀取配置文件類(lèi) 中,CommonHelper.To() 方法實(shí)現(xiàn)類(lèi)型的轉(zhuǎn)換,用到了TypeConverter 類(lèi)。學(xué)習(xí)記錄一下用法。
TypeConverter 實(shí)現(xiàn)兩個(gè)類(lèi)的互相轉(zhuǎn)換。 通過(guò)繼承TypeConverter按需實(shí)現(xiàn)4個(gè)方法來(lái)實(shí)現(xiàn)自定義類(lèi)型轉(zhuǎn)換。
?
public virtual object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) public virtual object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) public virtual bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) public virtual bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
?
GenericListTypeConverter.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; namespace Nop.Core.ComponentModel { public class GenericListTypeConverter<T> : TypeConverter { protected readonly TypeConverter _typeConverter; public GenericListTypeConverter() { _typeConverter = TypeDescriptor.GetConverter( typeof (T)); if (_typeConverter == null ) throw new InvalidOperationException( " No type converter exists for type " + typeof (T).FullName); } protected virtual string [] GetStringArray( string input) { if (! String.IsNullOrEmpty(input)) { string [] result = input.Split( ' , ' ); Array.ForEach(result, s => s.Trim()); return result; } else return new string [ 0 ]; } public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof ( string )) { string [] items = GetStringArray(sourceType.ToString()); return (items.Count() > 0 ); } return base .CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string ) { string [] items = GetStringArray(( string )value); var result = new List<T> (); Array.ForEach(items, s => { object item = _typeConverter.ConvertFromInvariantString(s); if (item != null ) { result.Add((T)item); } }); return result; } return base .ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof ( string )) { string result = string .Empty; if (((IList<T>)value) != null ) { // we don't use string.Join() because it doesn't support invariant culture for ( int i = 0 ; i < ((IList<T>)value).Count; i++ ) { var str1 = Convert.ToString(((IList<T> )value)[i], CultureInfo.InvariantCulture); result += str1; // don't add comma after the last element if (i != ((IList<T>)value).Count - 1 ) result += " , " ; } } return result; } return base .ConvertTo(context, culture, value, destinationType); }
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if ((destinationType == typeof (List<T>)) | (destinationType == typeof (InstanceDescriptor))) return true ; else return base .CanConvertTo(context, destinationType); }} }
?
Test代碼
[Test] public void CanConvertFromTest1() { TypeConverter typeConverter = new GenericListTypeConverter< string > (); var items = " 10,20,30,40,50 " ; var list = new List< string > (); if (typeConverter.CanConvertFrom( typeof ( string ))) { list = typeConverter.ConvertFrom(items) as List< string > ; } Assert.AreEqual(list.Count, 5 ); } [Test] public void CanConvertToTest1() { var items = new List< string > { " foo " , " bar " , " day " }; string result = "" ; TypeConverter typeConverter = new GenericListTypeConverter< string > (); result = typeConverter.ConvertTo(items, typeof ( string )) as string ; Assert.True(result.Length > 0 ); }
?
GenericListTypeConverter實(shí)現(xiàn)了 string,List<string>的互相轉(zhuǎn)換。
?
上面的代碼需要new 一個(gè) TypeConverter方法來(lái)實(shí)現(xiàn)轉(zhuǎn)換。另一種方法是使用Attribute特性附加在Class中,如下
[TypeConverter( typeof (Triangle.TriangleConverter))] public class Triangle { }
?
這樣做方便設(shè)計(jì)時(shí)和運(yùn)行時(shí)實(shí)現(xiàn)轉(zhuǎn)換。
// 獲取該類(lèi)的TypeConvert實(shí)例 var typeConvert = TypeDescriptor.GetConverter( typeof (Longitude))
?
如果有一下的需求,該如何使用TypeConvert?
1.如何為類(lèi)庫(kù)中的類(lèi)添加特性。
2.根據(jù)動(dòng)態(tài)的為類(lèi)添加TypeConvert。
3.為泛型類(lèi)添加TypeConvert。
?如下
TypeDescriptor.AddAttributes( typeof (List< string > ), new TypeConverterAttribute( typeof (GenericListTypeConverter< string >)));
?
Test代碼:
[SetUp] public void SetUp() { TypeDescriptor.AddAttributes( typeof (List< int > ), new TypeConverterAttribute( typeof (GenericListTypeConverter< int > ))); TypeDescriptor.AddAttributes( typeof (List< string > ), new TypeConverterAttribute( typeof (GenericListTypeConverter< string > ))); } [Test] public void Can_get_int_list_type_converter() { var converter = TypeDescriptor.GetConverter( typeof (List< int > )); converter.GetType().ShouldEqual( typeof (GenericListTypeConverter< int > )); } [Test] public void Can_get_string_list_type_converter() { var converter = TypeDescriptor.GetConverter( typeof (List< string > )); converter.GetType().ShouldEqual( typeof (GenericListTypeConverter< string > )); } [Test] public void Can_get_int_list_from_string() { var items = " 10,20,30,40,50 " ; var converter = TypeDescriptor.GetConverter( typeof (List< int > )); var result = converter.ConvertFrom(items) as IList< int > ; result.ShouldNotBeNull(); result.Count.ShouldEqual( 5 ); } [Test] public void Can_get_string_list_from_string() { var items = " foo, bar, day " ; var converter = TypeDescriptor.GetConverter( typeof (List< string > )); var result = converter.ConvertFrom(items) as List< string > ; result.ShouldNotBeNull(); result.Count.ShouldEqual( 3 ); }
?
參考:
http://www.cnblogs.com/ericwen/archive/2007/12/12/typeconvertattribute.html
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
