对一个C#通用类型转换器的改进

using System;
using System.Collections.Generic;
using System.Text;


namespace LoadXml
{
    /  
    ///     Copyright (C) 2009 Keepsoft  
    ///     All rights reserved  
    ///  
    ///     File:       TypeConverterGeneral.cs  
    ///     Author:     tianfj  
    ///     CreateDate: 2009-4-17 0:25:15  
    ///     Description:实现类型属性分别编辑的通用类型转换器  
    ///     
    ///     Author:     weekeew
    ///     PromoteData:2017-03-20 09:28:00
    ///     Description:optimize for string parse,support recursive assignment
    ///  
    /  
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
    using System.ComponentModel;
    using System.ComponentModel.Design.Serialization;
    using System.Globalization;
    using System.Reflection;


    namespace SkinSharpBuilder
    {
        /// <summary>     
        /// 实现类型属性分别编辑的通用类型转换器     
        /// 使用注意:使用的时候应该先从这个通用类型转换器中继承一个自己的类型转换器,泛型T应该是类型转换器的目标类型     
        /// </summary>     
        /// <typeparam name="T"></typeparam>     
        public class TypeConverterGeneral<T> : TypeConverter where T : new()
        {
            public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
            {
                return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType));
            }


            public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
            {
                //字符串类似:ClassName { A=a, B=b, C=c }     
                string strValue = value as string;
                if (strValue == null)
                {
                    return base.ConvertFrom(context, culture, value);
                }


                Type type = typeof(T);


                MethodInfo method = type.GetMethod("ObjectFromString");


                //按照用户自定义的转换
                if (method != null)
                {
                    Object objValue = Activator.CreateInstance(type);
                    method.Invoke(objValue, new object[] { strValue });


                    return objValue;
                }


                //按照默认的转换
                strValue = strValue.Trim();
                if (strValue.Length == 0)
                {
                    return null;
                }
                if (culture == null)
                {
                    culture = CultureInfo.CurrentCulture;
                }
                char sepChar = culture.TextInfo.ListSeparator[0];     
                //char sepChar = '|';


                1、去掉“ClassName { ”和“ }”两部分     
                //string withStart = type.Name + " { ";
                //string withEnd = " }";
                //int begin = strValue.IndexOf("{") + 1;
                //int end = strValue.LastIndexOf("}");
                //if (strValue.StartsWith(withStart) && strValue.EndsWith(withEnd))
                //{
                //    strValue = strValue.Substring(withStart.Length, strValue.Length - withStart.Length - withEnd.Length);
                //}
                //else
                //{
                //    strValue = strValue.Substring(begin, end-begin);
                //}
                //2、分割属性值     
                // string[] strArray = strValue.Split(new char[] { sepChar });
                 string[] strArray = Parse(strValue).ToArray();
                //3、做成属性集合表     
                Hashtable propertiesHashTable = new Hashtable();
                for (int i = 0; i < strArray.Length; i++)
                {
                    string str = strArray[i].Trim();
                    int index = str.IndexOf('=');
                    if (index != -1)
                    {
                        string propName = str.Substring(0, index);
                        string propValue = str.Substring(index + 1, str.Length - index - 1);
                        PropertyInfo pi = type.GetProperty(propName);
                        if (pi != null)
                        {
                            //该属性对应类型的类型转换器     
                            TypeConverter converter = TypeDescriptor.GetConverter(pi.PropertyType);
                            propertiesHashTable.Add(propName, converter.ConvertFromString(propValue));
                        }
                    }
                }


                return this.CreateInstance(context, propertiesHashTable);
            }


            public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
            {
                return ((destinationType == typeof(InstanceDescriptor)) || base.CanConvertTo(context, destinationType));
            }


            public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
            {
                if (destinationType == null)
                {
                    throw new ArgumentNullException("destinationType");
                }
                if (value is T)
                {
                    if (destinationType == typeof(string))
                    {
                        if (culture == null)
                        {
                            culture = CultureInfo.CurrentCulture;
                        }


                        Type type = value.GetType();
                        MethodInfo method = type.GetMethod("FormatToString");
                        if (method != null)
                        {
                            string stringValue = (string)method.Invoke(value, new object[0] { });
                            return stringValue;
                        }


                        //按照默认的转换
                        string separator = " | ";


                        StringBuilder sb = new StringBuilder();


                        sb.Append(type.Name + " { ");
                        PropertyInfo[] pis = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);


                        for (int i = 0; i < pis.Length; i++)
                        {
                            //if (!pis[i].CanRead) continue;


                            Type typeProp = pis[i].PropertyType;
                            string nameProp = pis[i].Name;
                            //object valueProp = pis[i].GetValue(value, null);


                            object valueProp = pis[i].CanRead ? pis[i].GetValue(value, null) : 0;


                            TypeConverter converter = TypeDescriptor.GetConverter(typeProp);


                            sb.AppendFormat("{0}={1}" + separator, nameProp, converter.ConvertToString(context, valueProp));
                        }


                        string strContent = sb.ToString();


                        if (strContent.EndsWith(separator))
                        {
                            strContent = strContent.Substring(0, strContent.Length - separator.Length);
                        }
                        strContent += " }";


                        return strContent;
                    }
                    if (destinationType == typeof(InstanceDescriptor))
                    {
                        ConstructorInfo constructor = typeof(T).GetConstructor(new Type[0]);
                        if (constructor != null)
                        {
                            return new InstanceDescriptor(constructor, new object[0], false);
                        }
                    }
                }
                return base.ConvertTo(context, culture, value, destinationType);
            }


            public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
            {
                if (propertyValues == null)
                {
                    throw new ArgumentNullException("propertyValues");
                }
                Type type = typeof(T);


                object obj = Activator.CreateInstance(type);
                /*
                ConstructorInfo ci = type.GetConstructor(new Type[0]);
                if (ci == null) return null;
               
                //调用默认的构造函数构造实例     
                object obj = ci.Invoke(new object[0]);
                 */


                //设置属性     
                PropertyInfo[] pis = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);


                object propValue = null;


                for (int i = 0; i < pis.Length; i++)
                {
                    if (!pis[i].CanWrite) continue;
                    propValue = propertyValues[pis[i].Name];
                    if (propValue != null)
                        pis[i].SetValue(obj, propValue, null);
                }


                return obj;
            }


            public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
            {
                return true;//返回更改此对象的值是否要求调用 CreateInstance 方法来创建新值。     
            }


            public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
            {
                //属性依照在类型中声明的顺序显示     
                Type type = value.GetType();
                PropertyInfo[] pis = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
                string[] names = new string[pis.Length];
                for (int i = 0; i < names.Length; i++)
                {
                    names[i] = pis[i].Name;
                }
                return TypeDescriptor.GetProperties(typeof(T), attributes).Sort(names);
            }


            public override bool GetPropertiesSupported(ITypeDescriptorContext context)
            {
                return true;
            }




            //在第一层大括号内,按照|分解即可        
            private List<string> Parse(string value)
            {
                List<string> props = new List<string>();
                string[] array = value.Split(new char[] { ' ' });
                StringBuilder sb = new StringBuilder();
                int LeftBracketCount = 0;


                for (int i = 0; i < array.Length; i++)
                {
                    string word = array[i];
                    switch (word)//当前的输入值
                    {
                        case "{":
                            LeftBracketCount++;
                            if (LeftBracketCount == 1)
                            {
                                Console.WriteLine(
                                    string.Format("ClassName:{0}", sb.ToString())
                                    );


                                sb.Remove(0, sb.Length);
                            }
                            else if (LeftBracketCount > 1)
                            {
                                sb.Append(" ");
                                sb.Append(word);
                            }


                            break;
                        case "=":


                            sb.Append(" ");
                            sb.Append(word);


                            break;


                        case "|":
                            if (LeftBracketCount == 1)
                            {
                                string prop = sb.ToString();
                                props.Add(prop);


                                sb.Remove(0, sb.Length);
                            }
                            else if (LeftBracketCount > 1)
                            {
                                sb.Append(" ");
                                sb.Append(word);
                            }


                            break;


                        case "}":
                            LeftBracketCount--;
                            if (LeftBracketCount == 0)
                            {
                                string prop = sb.ToString();
                                props.Add(prop);
                                sb.Remove(0, sb.Length);


                            }
                            else if (LeftBracketCount >= 1)
                            {
                                sb.Append(" ");
                                sb.Append(word);
                            }


                            break;


                        default:
                            sb.Append(" ");
                            sb.Append(word);
                            break;
                    }
                }

                return props;
            }

        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值