之前的一個 封裝讀取配置文件類 中,CommonHelper.To() 方法實現(xiàn)類型的轉(zhuǎn)換,用到了TypeConverter 類。學(xué)習(xí)記錄一下用法。
TypeConverter 實現(xiàn)兩個類的互相轉(zhuǎn)換。 通過繼承TypeConverter按需實現(xiàn)4個方法來實現(xiàn)自定義類型轉(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實現(xiàn)了 string,List<string>的互相轉(zhuǎn)換。
?
上面的代碼需要new 一個 TypeConverter方法來實現(xiàn)轉(zhuǎn)換。另一種方法是使用Attribute特性附加在Class中,如下
[TypeConverter(
typeof
(Triangle.TriangleConverter))]
public
class
Triangle
{
}
?
這樣做方便設(shè)計時和運行時實現(xiàn)轉(zhuǎn)換。
//
獲取該類的TypeConvert實例
var
typeConvert = TypeDescriptor.GetConverter(
typeof
(Longitude))
?
如果有一下的需求,該如何使用TypeConvert?
1.如何為類庫中的類添加特性。
2.根據(jù)動態(tài)的為類添加TypeConvert。
3.為泛型類添加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號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

