PropertiesManager.cs 6.16 KB
Newer Older
潘栩锋's avatar
潘栩锋 committed
1 2 3 4 5
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
6
using System.Text.RegularExpressions;
潘栩锋's avatar
潘栩锋 committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

namespace Misc
{
    public static class PropertiesManager
    {

        /// <summary>
        /// 获取所有属性名。
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<string> GetAllPropertyNames(object obj)
        {
            PropertyInfo[] properties = obj.GetType().GetProperties();

            return from p in properties select p.Name;
        }
23 24 25 26 27 28 29
        /// <summary>
        /// 获取所有属性名。
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<string> GetAllPropertyNames(Type type)
        {
            PropertyInfo[] properties = type.GetProperties();
潘栩锋's avatar
潘栩锋 committed
30

31 32
            return from p in properties select p.Name;
        }
潘栩锋's avatar
潘栩锋 committed
33 34 35 36 37 38 39 40
        /// <summary>
        /// 设定参数(属性)的值,触发属性值变化“通知”,writeVal
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName">属性名</param>
        /// <param name="v"></param>
        public static void SetValue(object obj, string propertyName, object v)
        {
41 42
            //if (!getRootProperty(ref obj, ref propertyName))
            //    return;
潘栩锋's avatar
潘栩锋 committed
43 44 45 46 47 48 49
            PropertyInfo property = obj.GetType().GetProperty(propertyName);
            if (property != null)
            {
                property.SetValue(obj, v, null);
            }
        }

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
        static bool getRootProperty(ref object obj, ref string propertyName) {
            Regex r = new Regex(@"(\S+)\[(\d+)\]");

            string[] lvs = propertyName.Split('.');
            if (lvs.Count() > 1)
            {
                //这个是多级的
                for (int i = 0; i < lvs.Count() - 1; i++)
                {
                    PropertyInfo property;
                    string name = lvs[i];
                    int index = 0;
                    var match = r.Match(name);
                    if (match.Success)
                    {
                        name = match.Groups[1].Value;
                        index = int.Parse(match.Groups[2].Value);
                    }
                    property = obj.GetType().GetProperty(name);
                    if (property == null)
                        return false;//异常
                    if(match.Success)
                        obj = property.GetValue(obj,new object[] { index });
                    else
                        obj = property.GetValue(obj);
                }
                propertyName = lvs.Last();
            }
            return true;
        }
潘栩锋's avatar
潘栩锋 committed
80 81 82 83 84 85 86 87
        /// <summary>
        /// 设定参数(属性)的值,触发属性值变化“通知”,writeVal
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <param name="val"></param>
        public static void SetValue(object obj, string propertyName, string val)
        {
88 89 90
            //if (!getRootProperty(ref obj, ref propertyName))
            //    return;

潘栩锋's avatar
潘栩锋 committed
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
            PropertyInfo property = obj.GetType().GetProperty(propertyName);
            if (property != null)
            {
                object v = Converter.Parse(val, property.PropertyType);
                property.SetValue(obj, v, null);
            }
        }

        /// <summary>
        /// 获取设定的属性值,writeVal
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public static object GetValue(object obj, string propertyName)
        {
107 108 109
            //if (!getRootProperty(ref obj, ref propertyName))
            //    return null;

潘栩锋's avatar
潘栩锋 committed
110 111 112 113 114 115 116 117 118
            PropertyInfo property = obj.GetType().GetProperty(propertyName);
            if (property != null)
            {
                return property.GetValue(obj, null);
            }
            else
                return null;
        }

潘栩锋's avatar
潘栩锋 committed
119

潘栩锋's avatar
潘栩锋 committed
120 121 122 123 124
        /// <summary>
        /// 把 src内的全部属性,复制到 dest
        /// </summary>
        /// <param name="src"></param>
        /// <param name="dest"></param>
潘栩锋's avatar
潘栩锋 committed
125
        public static void CopyTo(object src, object dest)
潘栩锋's avatar
潘栩锋 committed
126
        {
潘栩锋's avatar
潘栩锋 committed
127 128 129 130 131 132
            Type t = src.GetType();
            if (src.GetType() != dest.GetType())
            {
                throw new Exception("CopyTo src.GetType() != dest.GetType()");
            }

潘栩锋's avatar
潘栩锋 committed
133 134
            foreach (PropertyInfo propertyInfo in t.GetProperties())
            {
潘栩锋's avatar
1  
潘栩锋 committed
135 136 137 138 139 140 141
                //忽略不复制!!!
                if (propertyInfo.GetCustomAttributes(typeof(CopyIgnoreAttribute), false).Count() > 0)
                    continue;

                //ICopiable
                //if (propertyInfo.PropertyType.IsSubclassOf(typeof(ICopiable)))
                if(typeof(ICopiable).IsAssignableFrom(propertyInfo.PropertyType))
潘栩锋's avatar
1  
潘栩锋 committed
142
                {
潘栩锋's avatar
1  
潘栩锋 committed
143 144
                    ICopiable copiable = propertyInfo.GetValue(dest, null) as ICopiable;
                    copiable.Copy(propertyInfo.GetValue(src, null));
潘栩锋's avatar
1  
潘栩锋 committed
145
                }
潘栩锋's avatar
1  
潘栩锋 committed
146
                else if(propertyInfo.CanWrite)
潘栩锋's avatar
潘栩锋 committed
147
                {
潘栩锋's avatar
1  
潘栩锋 committed
148
                    propertyInfo.SetValue(dest, propertyInfo.GetValue(src, null), null);
潘栩锋's avatar
潘栩锋 committed
149
                }
潘栩锋's avatar
潘栩锋 committed
150 151
            }
        }
潘栩锋's avatar
1  
潘栩锋 committed
152

潘栩锋's avatar
潘栩锋 committed
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
        /// <summary>
        /// 检测 dest是否 实现了ICopiable,如果是,调用dest.Copy ;否 调用CopyTo(src,dest)
        /// </summary>
        /// <param name="src"></param>
        /// <param name="dest"></param>
        public static void AutoCopyTo(object src, object dest)
        {
            if (dest is ICopiable)
            {
                ((ICopiable)dest).Copy(src);
            }
            else
            {
                CopyTo(src, dest);
            }
        }

潘栩锋's avatar
潘栩锋 committed
170
    }
潘栩锋's avatar
潘栩锋 committed
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185

    /// <summary>
    /// 一般情况 用 Misc.PropertiesManager.CopyTo 就能解决问题
    /// 但 只有get的属性,是没法复制的
    /// 只能通过 继承 ICopiable, 解决 只能get 的属性 复制问题
    /// </summary>
    public interface ICopiable
    {
        /// <summary>
        /// 从 src 复制全部数据过来!!!
        /// 
        /// </summary>
        /// <param name="src"></param>
        void Copy(object src);
    }
潘栩锋's avatar
潘栩锋 committed
186
}