自定义控件属性使用TypeCoverter标记的类型的一些总结

这几天一直在跟TypeConverter 过不去,主要是要写一个 类型为List<String>的属性,必须要使用TypeConverter标记这个属性,结果...初学初学,快出血了,做一下总结

1]使用TypeConverter的意义
    举例:将属性值"1,2,3"转为{1,2,3}
2]继承TypeConverter需要提醒的事项
    无数文章提过必须要重写下列四个方法,不再重复
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
   public
 override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)  

public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)

设定环境如下,方便以后叙述
    public class testConverter : TypeConverter
{
///...
}


    [TypeConverter(
typeof(testConverter))]
    
public class testList : List<String>
{
///...
}


public class testControl:WebControl,...
{
public testList test
{
get{...}
set{...}
}

///...
}
重写ConvertTo(...)/CanConvertTo(...)这两个方法的时候,无数的文章也提及需要实现
destinationType == typeof(InstanceDescriptor))这个条件下的代码,但是并未提及原因

3]实现destinationType == typeof(InstanceDescriptor))这个条件下的代码的原因
引用microsoft的ASP.NET服务器控件与组件开发的相关叙述
当某个属性是可读写时,就需要将属性的类型转换成InstanceDescriptor类型,并且解析器也需要产生创建该类型的实力的代码
...
InstanceDescriptor对象提供了用来创建以参数类型传递给ConvertTo方法的testList实例的构造器的有关信息。这些信息是解析器产生创建testList类型的一个实例的代码时所使用的

///PS:实例名根据本文修改过了

换个通俗点的说法,就是当解析testControl控件的时候,需要通知解析器InstanceDescriptor所叙述的构造函数,解析器用被通知的构造函数对testList实例进行构造,在使用可读写的属性是必须要实现这一步

4]实现destinationType == typeof(InstanceDescriptor))这个条件下的代码所需要注意的事
写程序的时候出现了一些问题,郁闷很久,其实实在只是C#基础问题,学的不扎实...
编译时所提示的错误是"未将对象引用设置到对象的实例"
将这个问题抽象出来,用Microsoft的代码来解释这个问题,先看看Microsoft的"ASP.NET服务器控件与组件开发"的实现方法,这个实现中MapPoint类类似point类

public override object ConverTo(...)
{
...
if (destinationType==typeof(InstanceDescriptor))
{
if(value==null){
return null;
}

MemberInfo mi 
= null;
object[] args=null;
MapPoint point 
= (MapPoint) value;
if (Point.IsEmpty){
mi 
= typeof(MapPoint).GetConstructor(new Type[0]);
}

else{
Type intType 
= typeof(int);
mi 
= typeof(MapPoint).GetConstructor(new type[]{intType,intType});
args 
= new object[](point.X,point.Y);
}

if (mi!=nullreturn new InstanceDescriptor(mi,args); else return null;
...
}
想了半天不知道为什么不写成

 

...
{
Type type
= typeof(MapPoint);
mi 
= typeof(MapPoint).GetConstructor(new type[]{type});
args 
= new object[](point);
......
}

并在MapPoint类中实现MapPoint(MapPoint _t)的构造方法

查了些文献才知道C#没有复制构造函数,需要自己编写,MSDN说明方法如下
http://msdn2.microsoft.com/zh-cn/library/ms173116(VS.80).aspx
但是尝试了一下并未成功...不知道为什么,原因待查

如果用Microsoft这种值传递,对于数组型类就比较麻烦,可以将类值串行化,在编写使用串行化对象的构造函数

posted @ 2007-11-01 19:22  Tachikoma  阅读(891)  评论(0编辑  收藏  举报