这是一个支持列表、字典和嵌套属性的辅助类,如果您需要支持多个索引器(非常罕见的情况),您应该扩展它。
public static class Helper
{
public static void SetProperty(object instance, string propery, object value)
{
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
var properties = propery.Split('.');
var type = instance.GetType();
object[] index = null;
PropertyInfo property = null;
for (var i = 0; i < properties.Length; i++)
{
var indexValue = Regex.Match(properties[i], @"(?<=\[)(.*?)(?=\])").Value;
if (string.IsNullOrEmpty(indexValue))
{
property = type.GetProperty(properties[i], flags);
index = null;
}
else
{
property =
type.GetProperty(properties[i].Replace(string.Format("[{0}]", indexValue), string.Empty),
flags);
index = GetIndex(indexValue, property);
}
if (i < properties.Length - 1)
instance = property.GetValue(instance, index);
type = instance.GetType();
}
property.SetValue(instance, value, index);
}
public static object GetProperty(object instance, string propery)
{
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
var properties = propery.Split('.');
var type = instance.GetType();
foreach (var p in properties)
{
var indexValue = Regex.Match(p, @"(?<=\[)(.*?)(?=\])").Value;
object[] index;
PropertyInfo property;
if (string.IsNullOrEmpty(indexValue))
{
property = type.GetProperty(p, flags);
index = null;
}
else
{
property =
type.GetProperty(p.Replace(string.Format("[{0}]", indexValue), string.Empty),
flags);
index = GetIndex(indexValue, property);
}
instance = property.GetValue(instance, index);
type = instance.GetType();
}
return instance;
}
private static object[] GetIndex(string indicesValue, PropertyInfo property)
{
var parameters = indicesValue.Split(',');
var parameterTypes = property.GetIndexParameters();
var index = new object[parameterTypes.Length];
for (var i = 0; i < parameterTypes.Length; i++)
index[i] = parameterTypes[i].ParameterType.IsEnum
? Enum.Parse(parameterTypes[i].ParameterType, parameters[i])
: Convert.ChangeType(parameters[i], parameterTypes[i].ParameterType);
return index;
}
}
这里有一些例子:
public enum Qwerty
{
Q,W,E,R,T,Y
}
class A
{
private int[,] _array=new int[10,10];
public B PropertyB { get; set; }
public int this[int i, int j]
{
get { return _array[i, j]; }
set { _array[i, j] = value; }
}
}
class B
{
public int Value { get; set; }
}
嵌套属性:
var a = new A { PropertyB = new B() };
Helper.SetProperty(a, "PropertyB.Value", 100);
var value = Helper.GetProperty(a, "PropertyB.Value");
索引器(具有多个索引):
var a = new A { PropertyB = new B() };
Helper.SetProperty(a, "Item[1,1]", 100);
var value = Helper.GetProperty(a, "Item[1,1]");
列表:
var list = new List<int>() { 0, 1, 2, 3, 4 };
Helper.SetProperty(list, "Item[2]", 200);
var value = Helper.GetProperty(list, "Item[2]");
带有列表的嵌套属性:
var list = new List<A>() { new A { PropertyB = new B() } };
Helper.SetProperty(list, "Item[0].PropertyB.Value", 75);
var value = Helper.GetProperty(list, "Item[0].PropertyB.Value");
字典:
var dic = new Dictionary<int, A> { { 100, new A { PropertyB = new B() } } };
var newA = new A { PropertyB = new B() { Value = 45 } };
Helper.SetProperty(dic, "Item[100]", newA);
var value = Helper.GetProperty(dic, "Item[100].PropertyB.Value");
以枚举为键的字典:
var dic = new Dictionary<Qwerty, A> { { Qwerty.Q, new A { PropertyB = new B() } } };
var newA = new A { PropertyB = new B() { Value = 45 } };
Helper.SetProperty(dic, "Item[Q]", newA);
var value = Helper.GetProperty(dic, "Item[Q].PropertyB.Value");
枚举为值:
var list = new List<Qwerty>() { Qwerty.Q, Qwerty.W, Qwerty.E, Qwerty.R, Qwerty.T, Qwerty.Y };
Helper.SetProperty(list, "Item[2]", Qwerty.Q);
var value = Helper.GetProperty(list, "Item[2]");