我试图在我的代码中使用Reflection1示例实现数据转换。
GetSourceValue函数有一个比较各种类型的开关,但我想删除这些类型和属性,并让GetSourceValue只使用一个字符串作为参数来获取属性的值。我想在字符串中传递一个类和属性,并解析属性的值。
这可能吗?
1原始博客文章的Web存档版本
我试图在我的代码中使用Reflection1示例实现数据转换。
GetSourceValue函数有一个比较各种类型的开关,但我想删除这些类型和属性,并让GetSourceValue只使用一个字符串作为参数来获取属性的值。我想在字符串中传递一个类和属性,并解析属性的值。
这可能吗?
1原始博客文章的Web存档版本
当前回答
这样怎么样:
public static Object GetPropValue(this Object obj, String name) {
foreach (String part in name.Split('.')) {
if (obj == null) { return null; }
Type type = obj.GetType();
PropertyInfo info = type.GetProperty(part);
if (info == null) { return null; }
obj = info.GetValue(obj, null);
}
return obj;
}
public static T GetPropValue<T>(this Object obj, String name) {
Object retval = GetPropValue(obj, name);
if (retval == null) { return default(T); }
// throws InvalidCastException if types are incompatible
return (T) retval;
}
这将允许你使用单个字符串进入属性,就像这样:
DateTime now = DateTime.Now;
int min = GetPropValue<int>(now, "TimeOfDay.Minutes");
int hrs = now.GetPropValue<int>("TimeOfDay.Hours");
您可以将这些方法用作静态方法或扩展。
其他回答
jheddings和AlexD都写了关于如何解析属性字符串的出色答案。我想把我的库也加入其中,因为我专门为此编写了一个库。
路径。CSharp的主类是Resolver。默认情况下,它可以解析属性、数组和字典条目。
举个例子,如果你有一个这样的物体
var o = new { Property1 = new { Property2 = "value" } };
想要获得Property2,你可以这样做:
IResolver resolver = new Resolver();
var path = "Property1.Property2";
object result = r.Resolve(o, path);
//=> "value"
这是它可以解析的路径的最基本示例。如果你想看看它还能做什么,或者你可以如何扩展它,只需前往它的Github页面。
jheddings的回答很好。我想通过允许引用聚集的数组或对象的集合来改进它,这样propertyName可以是property1.property2[X].property3:
public static object GetPropertyValue(object srcobj, string propertyName)
{
if (srcobj == null)
return null;
object obj = srcobj;
// Split property name to parts (propertyName could be hierarchical, like obj.subobj.subobj.property
string[] propertyNameParts = propertyName.Split('.');
foreach (string propertyNamePart in propertyNameParts)
{
if (obj == null) return null;
// propertyNamePart could contain reference to specific
// element (by index) inside a collection
if (!propertyNamePart.Contains("["))
{
PropertyInfo pi = obj.GetType().GetProperty(propertyNamePart);
if (pi == null) return null;
obj = pi.GetValue(obj, null);
}
else
{ // propertyNamePart is areference to specific element
// (by index) inside a collection
// like AggregatedCollection[123]
// get collection name and element index
int indexStart = propertyNamePart.IndexOf("[")+1;
string collectionPropertyName = propertyNamePart.Substring(0, indexStart-1);
int collectionElementIndex = Int32.Parse(propertyNamePart.Substring(indexStart, propertyNamePart.Length-indexStart-1));
// get collection object
PropertyInfo pi = obj.GetType().GetProperty(collectionPropertyName);
if (pi == null) return null;
object unknownCollection = pi.GetValue(obj, null);
// try to process the collection as array
if (unknownCollection.GetType().IsArray)
{
object[] collectionAsArray = unknownCollection as object[];
obj = collectionAsArray[collectionElementIndex];
}
else
{
// try to process the collection as IList
System.Collections.IList collectionAsList = unknownCollection as System.Collections.IList;
if (collectionAsList != null)
{
obj = collectionAsList[collectionElementIndex];
}
else
{
// ??? Unsupported collection type
}
}
}
}
return obj;
}
当你想要遍历对象中的所有属性,然后使用属性的每个值时,必须使用这段代码:
foreach (var property in request.GetType().GetProperties())
{
var valueOfProperty = property.GetValue(properties, null);
}
捷径....
var a = new Test { Id = 1 , Name = "A" , date = DateTime.Now};
var b = new Test { Id = 1 , Name = "AXXX", date = DateTime.Now };
var compare = string.Join("",a.GetType().GetProperties().Select(x => x.GetValue(a)).ToArray())==
string.Join("",b.GetType().GetProperties().Select(x => x.GetValue(b)).ToArray());
public static List<KeyValuePair<string, string>> GetProperties(object item) //where T : class
{
var result = new List<KeyValuePair<string, string>>();
if (item != null)
{
var type = item.GetType();
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var pi in properties)
{
var selfValue = type.GetProperty(pi.Name).GetValue(item, null);
if (selfValue != null)
{
result.Add(new KeyValuePair<string, string>(pi.Name, selfValue.ToString()));
}
else
{
result.Add(new KeyValuePair<string, string>(pi.Name, null));
}
}
}
return result;
}
这是一种在List中获取所有属性及其值的方法。