• 深度解析 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

  • 相关阅读:
    SDN第四次上机作业
    SDN第四次作业
    SDN第三次上机作业
    SDN第三次作业
    SDN第二次上机作业
    SDN第二次作业
    个人作业——软件产品案例分析(待更)
    软工 实验三 需求分析(沈樟伟组)
    个人博客二:需求分析
    微软小娜APP的案例分析
  • 原文地址:https://www.cnblogs.com/wsion/p/3030218.html
Copyright © 2020-2023  润新知