using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
namespace Misc
{
public static class PropertiesManager
{
///
/// 获取所有属性名。
///
///
public static IEnumerable GetAllPropertyNames(object obj)
{
PropertyInfo[] properties = obj.GetType().GetProperties();
return from p in properties select p.Name;
}
///
/// 获取所有属性名。
///
///
public static IEnumerable GetAllPropertyNames(Type type)
{
PropertyInfo[] properties = type.GetProperties();
return from p in properties select p.Name;
}
///
/// 设定参数(属性)的值,触发属性值变化“通知”,writeVal
///
///
/// 属性名
///
public static void SetValue(object obj, string propertyName, object v)
{
//if (!getRootProperty(ref obj, ref propertyName))
// return;
PropertyInfo property = obj.GetType().GetProperty(propertyName);
if (property != null)
{
property.SetValue(obj, v, null);
}
}
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;
}
///
/// 设定参数(属性)的值,触发属性值变化“通知”,writeVal
///
///
///
///
public static void SetValue(object obj, string propertyName, string val)
{
//if (!getRootProperty(ref obj, ref propertyName))
// return;
PropertyInfo property = obj.GetType().GetProperty(propertyName);
if (property != null)
{
object v = Converter.Parse(val, property.PropertyType);
property.SetValue(obj, v, null);
}
}
///
/// 获取设定的属性值,writeVal
///
///
///
///
public static object GetValue(object obj, string propertyName)
{
//if (!getRootProperty(ref obj, ref propertyName))
// return null;
PropertyInfo property = obj.GetType().GetProperty(propertyName);
if (property != null)
{
return property.GetValue(obj, null);
}
else
return null;
}
///
/// 把 src内的全部属性,复制到 dest
///
///
///
public static void CopyTo(object src, object dest)
{
Type t = src.GetType();
if (!src.GetType().IsAssignableFrom(dest.GetType()))
{
throw new Exception("CopyTo src.GetType() != dest.GetType()");
}
foreach (PropertyInfo propertyInfo in t.GetProperties())
{
//忽略不复制!!!
if (propertyInfo.GetCustomAttributes(typeof(CopyIgnoreAttribute), false).Count() > 0)
continue;
//ICopiable
//if (propertyInfo.PropertyType.IsSubclassOf(typeof(ICopiable)))
if(typeof(ICopiable).IsAssignableFrom(propertyInfo.PropertyType))
{
ICopiable copiable = propertyInfo.GetValue(dest, null) as ICopiable;
copiable.Copy(propertyInfo.GetValue(src, null));
}
else if(propertyInfo.CanWrite)
{
propertyInfo.SetValue(dest, propertyInfo.GetValue(src, null), null);
}
}
}
///
/// 检测 dest是否 实现了ICopiable,如果是,调用dest.Copy ;否 调用CopyTo(src,dest)
///
///
///
public static void AutoCopyTo(object src, object dest)
{
if (dest is ICopiable)
{
((ICopiable)dest).Copy(src);
}
else
{
CopyTo(src, dest);
}
}
}
///
/// 一般情况 用 Misc.PropertiesManager.CopyTo 就能解决问题
/// 但 只有get的属性,是没法复制的
/// 只能通过 继承 ICopiable, 解决 只能get 的属性 复制问题
///
public interface ICopiable
{
///
/// 从 src 复制全部数据过来!!!
///
///
///
void Copy(object src);
}
}