TypeConverter学习

系统 1667 0

之前的一个 封装读取配置文件类 中,CommonHelper.To() 方法实现类型的转换,用到了TypeConverter 类。学习记录一下用法。

TypeConverter 实现两个类的互相转换。 通过继承TypeConverter按需实现4个方法来实现自定义类型转换。

 

      
        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实现了 string,List<string>的互相转换。

 

上面的代码需要new 一个 TypeConverter方法来实现转换。另一种方法是使用Attribute特性附加在Class中,如下

      [TypeConverter(
      
        typeof
      
      
        (Triangle.TriangleConverter))]

    
      
      
        public
      
      
        class
      
      
         Triangle

    {

    }
      
    

 

这样做方便设计时和运行时实现转换。

      
        //
      
      
        获取该类的TypeConvert实例
      
      
        var
      
       typeConvert =  TypeDescriptor.GetConverter(
      
        typeof
      
      (Longitude))
    

 

如果有一下的需求,该如何使用TypeConvert?

1.如何为类库中的类添加特性。

2.根据动态的为类添加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

TypeConverter学习


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论