代码改变世界

TypeConverter的使用

2013-12-13 10:54  地图315  阅读(351)  评论(0编辑  收藏  举报

我们知道,C#中有int.Parse,int.TryParse这样神奇的功能,那它们又是如何做到的呢?我们试着自己也来自定义一个“转换器”。

  首先,定义一个类:

    public class Human
    {
        public string Name { get; set; }

        public Human Child { get; set; }
    }

  这个类具有两个属性:

  · string类型的Name

  · Human类型的Child

 

  现在,我期望为Human实例的Child属性赋一个Human类型的值,并且Child.Name就是这个字符串的值。

  我们先在Button1_Click事件中尝试着这样写:

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            Human h = (Human)this.FindResource("human");
            MessageBox.Show(h.Child.Name);
        }

  运行后报错,告诉Child不存在,为什么Child不存在呢?原因很简单,Human实例的Child属性是Human类型,而“ABC”是一个字符串,编译器不知道如何将一个字符串实例转换成一个Human实例。那我们应该怎么做呢?办法是使用TypeConverter和TypeConvertAttribute这两个类。
  

  首先,我们要从TypeConverter中派生出自己的类,并重写它的一个ConvertFrom方法。这个方法有一个参数名为value,我们要做的就是讲这个值“翻译”成合适的值赋给对象的属性:

复制代码
using System.ComponentModel;


    public class StringToHumanTypeConverter : TypeConverter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
            {
                Human h = new Human();
                h.Name = value as string;
                return h;
            }

            return base.ConvertFrom(context, culture, value);
        }
    }
复制代码

  有了这个类还不够,还要使用TypeConverterAttribute这个特征类把StringToHumanTypeConverter这个类“粘贴”到作为目标的Human类上。

复制代码
    [TypeConverterAttribute(typeof(StringToHumanTypeConverter))]
    public class Human
    {
        public string Name { get; set; }

        public Human Child { get; set; }
    }
复制代码

  因为特征类在使用的时候可以省略Attribute这个词,所以也可以写成:

复制代码
    [TypeConverter(typeof(StringToHumanTypeConverter))]
    public class Human
    {
        public string Name { get; set; }

        public Human Child { get; set; }
    }
复制代码

  但这样写,我们需要认清写在方括号里的是TypeConverterAttribute而不是TypeConverter。

  完成之后,再单击按钮,想要的结果就弹出来了。