我们知道,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。
完成之后,再单击按钮,想要的结果就弹出来了。