zoukankan      html  css  js  c++  java
  • 深度解析 TypeConverter & TypeConverterAttribute (二)

    TypeConverterAttribute Class
        TypeConverterAttribute 其实就是一个继承Attribute的类,使用[TypeConverter(typeof(MyClassConverter))]标签施加到程序实体 上。根据TypeConverterAttritue的定义知道这个属性Attribute可以施加到所有实体上。

        [AttributeUsageAttribute(AttributeTargets.All)] 
        
    public sealed class TypeConverterAttribute : Attribute

    如果你对Attribute不太了解可以先看看dudu的阐释,或者看看http://www.codeproject.com/KB/cs/attributes.aspx
    Attribute是一种新的申明方式,它可以在是设计时和运行时作用于它附加的Program Entities上。
    上篇我们定义了class Longitude 和 class LongitudeTypeConverter,然后我们做了个Test,实现了转换的目的。
    但要在设计时或在运行时起作用,就是说在这两种情况LongitudeTypeConverter“自动的”帮助Longitude 实例于其他实例转换,需要TypeConverterAttribute的帮忙。
    在coding中我们很惊奇的发现,只用在Longitude类上附加TypeConverterAttribute标签,这两者就能关联起来。为什么呢?

     [TypeConverter(typeof(LongitudeTypeConverter))]
        
    public class Longitude
        
    {}

    那是因为如果一个类附件了Attribute,那么这个类就可以通过反射方法得到这个类属性,还可以通过TypeDescriptor.GetConverter静态方法获得这个类相关转换类的实例。这样就轻松的关联起来了。比如Test

    class Test
        
    {
            
    public static void Main(string[] args)
            
    {
                
    //将Longitude类转换到string类型
                Longitude longitude = new Longitude(10,11,12,LongitudeDirection.East);
                LongitudeTypeConverter converter 
    = new LongitudeTypeConverter();

                
    string strLongitude="";
                
    if (converter.CanConvertTo(typeof(string)))
                
    {
                    
    //Longitude 类没有附件TypeconverterAttribute时
                    strLongitude = (string)converter.ConvertTo(longitude, typeof(string));
                    
    //Longitude 类附件了TypeconverterAttribute时
                    strLongitude = (string)TypeDescriptor.GetConverter(typeof(Longitude)).ConvertTo(longitude, typeof(string));
                }

                System.Console.WriteLine(strLongitude);

                
    //将string还原回Longitude类
                Longitude longitude1 = new Longitude();
                
    if (converter.CanConvertFrom(typeof(string)))
                
    {
                    
    //Longitude 类没有附件TypeconverterAttribute时
                    longitude1 = (Longitude)converter.ConvertFrom(strLongitude);
                    
    //Longitude 类附件了TypeconverterAttribute时
                    longitude1 = (Longitude)TypeDescriptor.GetConverter(typeof(Longitude)).ConvertFrom(strLongitude);
                }

                System.Console.WriteLine(longitude1.Degrees);
                System.Console.WriteLine(longitude1.Direction);
                System.Console.WriteLine(longitude1.Minutes);
                System.Console.WriteLine(longitude1.Seconds);

            }

        }

    上面是在运行时,如果Longitude类的方法或字段也附加了相应的ConverterAttribute,我们也可以通过反射的方法得到附加ConverterAttribute的方法或字段。
    例如,

     Type type = typeof(Longitude);
                
    //AttributeTargs包括method实体
                CustomTypeConverterAttribute customTypeConverterAttribute;

                
    foreach (Attribute att in type.GetCustomAttributes(typeof(OtherTypeConverter), true))
                
    {
                    System.Console.WriteLine(
    "OtherTypeConverter 的属性Property" + customTypeConverterAttribute.Property1);
                }


                
    foreach (MethodInfo method in type.GetMethods())
                
    {
                    
    foreach (Attribute att in method.GetCustomAttributes(true))
                    
    {
                        customTypeConverterAttribute 
    = att as CustomTypeConverterAttribute;
                        
    if (null != customTypeConverterAttribute)
                        
    {
                            System.Console.WriteLine(
    "类的方法是:" + method.Name + " 该方法的附加Attribute是:" + customTypeConverterAttribute.ToString());
                        }

                    }

                }


    如果你想test上面的代码,需要自己完成CustomTypeConverterAttribute。

    在 设计时的应用,例如在复杂控件中的一个属性为一个类,我们需要在property browser中以string的形式输入值来初始化或构造这个属性property,我们需要在这个属性property上附件属性 DesignerSerializationVisibility标签。
    例如

     [Bindable(true)]
            [Category(
    "Appearance")]
            [DefaultValue(
    typeof(GPSLocation), "")]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [PersistenceMode(PersistenceMode.InnerProperty)]
            
    public GPSLocation Location
            
    {
                
    get
                
    {
                    
    // if no instance created yet do so
                    if (_Location == null)
                        _Location 
    = new GPSLocation();

                    
    return _Location;
                }

            }


    上面还有PersistenceMode属性标签,其表示代码在asp.net页面显示(也可以说是持久)的方式,有几种详见http://www.cnblogs.com/thinhunan/archive/2006/12/10/588341.html

    这样就可以达到效果如下([PersistenceMode(PersistenceMode.Attribute)]

    <ui:LocationControl ID="LocationControl1" runat="server" 
            Location
    -GPSLatitude="12N1'2"" Location-GPSLongitude="24W3'4"">
    </ui:LocationControl>

    [PersistenceMode(PersistenceMode.InnerProperty)]

    <ui:LocationControl ID="LocationControl1" runat="server">
       
    <Location GPSLatitude="12N1'3"" GPSLongitude="24W3'4"" />
    </ui:LocationControl>


    参考
    http://www.codeproject.com/KB/webforms/TypeConverters.aspx
    http://www.codeproject.com/KB/cs/attributes.aspx
    dudu:Attribute系列 http://www.cnblogs.com/ericwen/favorite/115549.html

    不对之处请批评指正。

    测试代码

    转载自http://blog.csdn.net/luyifeiniu/article/details/5107839

  • 相关阅读:
    hdu 1823 Luck and Love 二维线段树
    UVA 12299 RMQ with Shifts 线段树
    HDU 4578 Transformation 线段树
    FZU 2105 Digits Count 线段树
    UVA 1513 Movie collection 树状数组
    UVA 1292 Strategic game 树形DP
    【ACM】hdu_zs2_1003_Problem C_201308031012
    qsort快速排序
    【ACM】nyoj_7_街区最短路径问题_201308051737
    【ACM】nyoj_540_奇怪的排序_201308050951
  • 原文地址:https://www.cnblogs.com/wsion/p/3030218.html
Copyright © 2011-2022 走看看