我正在尝试在代码中使用Reflection 1示例实现数据转换 。

GetSourceValue函数具有比较各种类型的开关,但是我想删除这些类型和属性,并让GetSourceValue仅使用单个字符串作为参数来获取属性的值。 我想在字符串中传递类和属性,并解析该属性的值。

这可能吗?

1个原始博客文章的Web存档版本


#1楼

 public static object GetPropValue(object src, string propName){return src.GetType().GetProperty(propName).GetValue(src, null);}

当然,您将需要添加验证等功能,但这就是要点。


#2楼

这样的事情怎么样:

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 incompatiblereturn (T) retval;
}

这将允许您使用单个字符串进入属性,如下所示:

DateTime now = DateTime.Now;
int min = GetPropValue<int>(now, "TimeOfDay.Minutes");
int hrs = now.GetPropValue<int>("TimeOfDay.Hours");

您可以将这些方法用作静态方法或扩展。


#3楼

您永远不会提及要检查的对象,并且由于您拒绝引用给定对象的对象,因此我假设您的意思是静态对象。

using System.Reflection;
public object GetPropValue(string prop)
{int splitPoint = prop.LastIndexOf('.');Type type = Assembly.GetEntryAssembly().GetType(prop.Substring(0, splitPoint));object obj = null;return type.GetProperty(prop.Substring(splitPoint + 1)).GetValue(obj, null);
}

请注意,我用局部变量obj标记了要检查的objnull表示静态,否则将其设置为所需的值。 还请注意, GetEntryAssembly()是获取“运行中”程序集的几种可用方法之一,如果在加载类型时遇到困难,则可能需要使用它。


#4楼

使用Microsoft.VisualBasic命名空间( Microsoft.VisualBasic.dll )的CallByName怎么办? 它使用反射来获取常规对象,COM对象甚至动态对象的属性,字段和方法。

using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;

然后

Versioned.CallByName(this, "method/function/prop name", CallType.Get).ToString();

#5楼

使用System.Reflection命名空间的PropertyInfo。 无论我们尝试访问什么属性,反射都可以编译。 该错误将在运行时出现。

    public static object GetObjProperty(object obj, string property){Type t = obj.GetType();PropertyInfo p = t.GetProperty("Location");Point location = (Point)p.GetValue(obj, null);return location;}

获得对象的Location属性效果很好

Label1.Text = GetObjProperty(button1, "Location").ToString();

我们将获得Location:{X = 71,Y = 27}我们也可以以相同的方式返回location.X或location.Y。


#6楼

更短的方法....

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());

#7楼

添加到任何Class

public class Foo
{public object this[string propertyName]{get { return this.GetType().GetProperty(propertyName).GetValue(this, null); }set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); }}public string Bar { get; set; }
}

然后,您可以用作:

Foo f = new Foo();
// Set
f["Bar"] = "asdf";
// Get
string s = (string)f["Bar"];

#8楼

这是查找嵌套属性的另一种方法,该属性不需要字符串即可告诉您嵌套路径。 将单一属性方法归功于Ed S.。

    public static T FindNestedPropertyValue<T, N>(N model, string propName) {T retVal = default(T);bool found = false;PropertyInfo[] properties = typeof(N).GetProperties();foreach (PropertyInfo property in properties) {var currentProperty = property.GetValue(model, null);if (!found) {try {retVal = GetPropValue<T>(currentProperty, propName);found = true;} catch { }}}if (!found) {throw new Exception("Unable to find property: " + propName);}return retVal;}public static T GetPropValue<T>(object srcObject, string propName) {return (T)srcObject.GetType().GetProperty(propName).GetValue(srcObject, null);}

#9楼

以下代码是一种递归方法,用于显示对象实例中包含的所有属性名称和值的整个层次结构。 此方法在该线程中使用上面的AlexD的GetPropertyValue()答案的简化版本。 由于有了这个讨论线程,我得以弄清楚该如何做!

例如,通过使用如下方法,我使用此方法来显示WebService响应中所有属性的爆炸或转储:

PropertyValues_byRecursion("Response", response, false);

public static object GetPropertyValue(object srcObj, string propertyName)
{if (srcObj == null) {return null; }PropertyInfo pi = srcObj.GetType().GetProperty(propertyName.Replace("[]", ""));if (pi == null){return null;}return pi.GetValue(srcObj);
}public static void PropertyValues_byRecursion(string parentPath, object parentObj, bool showNullValues)
{/// Processes all of the objects contained in the parent object.///   If an object has a Property Value, then the value is written to the Console///   Else if the object is a container, then this method is called recursively///       using the current path and current object as parameters// Note:  If you do not want to see null values, set showNullValues = falseforeach (PropertyInfo pi in parentObj.GetType().GetTypeInfo().GetProperties()){// Build the current object property's namespace path.  // Recursion extends this to be the property's full namespace path.string currentPath = parentPath + "." + pi.Name;// Get the selected property's value as an objectobject myPropertyValue = GetPropertyValue(parentObj, pi.Name);if (myPropertyValue == null){// Instance of Property does not existif (showNullValues){Console.WriteLine(currentPath + " = null");// Note: If you are replacing these Console.Write... methods callback methods,//       consider passing DBNull.Value instead of null in any method object parameters.}}else if (myPropertyValue.GetType().IsArray){// myPropertyValue is an object instance of an Array of business objects.// Initialize an array index variable so we can show NamespacePath[idx] in the results.int idx = 0;foreach (object business in (Array)myPropertyValue){if (business == null){// Instance of Property does not exist// Not sure if this is possible in this context.if (showNullValues){Console.WriteLine(currentPath  + "[" + idx.ToString() + "]" + " = null");}}else if (business.GetType().IsArray){// myPropertyValue[idx] is another Array!// Let recursion process it.PropertyValues_byRecursion(currentPath + "[" + idx.ToString() + "]", business, showNullValues);}else if (business.GetType().IsSealed){// Display the Full Property Path and its ValueConsole.WriteLine(currentPath + "[" + idx.ToString() + "] = " + business.ToString());}else{// Unsealed Type Properties can contain child objects.// Recurse into my property value object to process its properties and child objects.PropertyValues_byRecursion(currentPath + "[" + idx.ToString() + "]", business, showNullValues);}idx++;}}else if (myPropertyValue.GetType().IsSealed){// myPropertyValue is a simple valueConsole.WriteLine(currentPath + " = " + myPropertyValue.ToString());}else{// Unsealed Type Properties can contain child objects.// Recurse into my property value object to process its properties and child objects.PropertyValues_byRecursion(currentPath, myPropertyValue, showNullValues);}}
}

#10楼

Dim NewHandle As YourType = CType(Microsoft.VisualBasic.CallByName(ObjectThatContainsYourVariable, "YourVariableName", CallType), YourType)

#11楼

关于嵌套属性的讨论,如果使用如下所示的DataBinder.Eval Method (Object, String) ,则可以避免所有反射:

var value = DataBinder.Eval(DateTime.Now, "TimeOfDay.Hours");

当然,您需要添加对System.Web程序集的引用,但这可能没什么大不了的。


#12楼

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;}

这是一种在列表中获取所有属性及其值的方法。


#13楼

jheddings和AlexD都就如何解析属性字符串写了出色的答案。 我想把我的东西混在一起,因为我正是为此目的编写了一个专用的库。

Pather.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页面 。


#14楼

如果我使用Ed S的代码,我会得到

“ ReflectionExtensions.GetProperty(Type,string)”由于其保护级别而无法访问

似乎Xamarin.Forms中没有GetProperty()TargetFrameworkProfileProfile7在我的便携式类库(.NET框架4.5,Windows 8中,ASP.NET 1.0的核心,Xamarin.Android,Xamarin.iOS,Xamarin.iOS经典)。

现在我找到了一个可行的解决方案:

using System.Linq;
using System.Reflection;public static object GetPropValue(object source, string propertyName)
{var property = source.GetType().GetRuntimeProperties().FirstOrDefault(p => string.Equals(p.Name, propertyName, StringComparison.OrdinalIgnoreCase));return property?.GetValue(source);
}

资源


#15楼

调用方法已在.NET Standard(自1.6版)中更改。 我们也可以使用C#6的空条件运算符。

using System.Reflection;
public static object GetPropValue(object src, string propName)
{return src.GetType().GetRuntimeProperty(propName)?.GetValue(src);
}

#16楼

public static TValue GetFieldValue<TValue>(this object instance, string name)
{var type = instance.GetType(); var field = type.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.FieldType) && e.Name == name);return (TValue)field?.GetValue(instance);
}public static TValue GetPropertyValue<TValue>(this object instance, string name)
{var type = instance.GetType();var field = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.PropertyType) && e.Name == name);return (TValue)field?.GetValue(instance);
}

#17楼

这是我的解决方案。 它也可以与COM对象一起使用,并允许从COM对象访问集合/数组项。

public static object GetPropValue(this object obj, string name)
{foreach (string part in name.Split('.')){if (obj == null) { return null; }Type type = obj.GetType();if (type.Name == "__ComObject"){if (part.Contains('[')){string partWithoundIndex = part;int index = ParseIndexFromPropertyName(ref partWithoundIndex);obj = Versioned.CallByName(obj, partWithoundIndex, CallType.Get, index);}else{obj = Versioned.CallByName(obj, part, CallType.Get);}}else{PropertyInfo info = type.GetProperty(part);if (info == null) { return null; }obj = info.GetValue(obj, null);}}return obj;
}private static int ParseIndexFromPropertyName(ref string name)
{int index = -1;int s = name.IndexOf('[') + 1;int e = name.IndexOf(']');if (e < s){throw new ArgumentException();}string tmp = name.Substring(s, e - s);index = Convert.ToInt32(tmp);name = name.Substring(0, s - 1);return index;
}

#18楼

public class YourClass
{//Add below line in your classpublic object this[string propertyName] => GetType().GetProperty(propertyName)?.GetValue(this, null);public string SampleProperty { get; set; }
}//And you can get value of any property like this.
var value = YourClass["SampleProperty"];

#19楼

以下方法最适合我:

class MyClass {public string prop1 { set; get; }public object this[string propertyName]{get { return this.GetType().GetProperty(propertyName).GetValue(this, null); }set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); }}
}

要获取属性值:

MyClass t1 = new MyClass();
...
string value = t1["prop1"].ToString();

设置属性值:

t1["prop1"] = value;

#20楼

看看Heleonix.Reflection库。 您可以通过路径获取/设置/调用成员,或者创建比反射更快的getter / setter(lambda编译为委托)。 例如:

var success = Reflector.Get(DateTime.Now, null, "Date.Year", out int value);

或一次创建一个吸气剂并缓存以备重用(这具有更高的性能,但如果中间成员为null,则可能会抛出NullReferenceException):

var getter = Reflector.CreateGetter<DateTime, int>("Date.Year", typeof(DateTime));
getter(DateTime.Now);

或者,如果您要创建具有不同getter的List<Action<object, object>> ,只需为编译的委托指定基本类型(类型转换将添加到编译的lambda中):

var getter = Reflector.CreateGetter<object, object>("Date.Year", typeof(DateTime));
getter(DateTime.Now);

#21楼

这是我根据其他答案得到的。 在错误处理方面变得如此具体有些过大的杀伤力。

public static T GetPropertyValue<T>(object sourceInstance, string targetPropertyName, bool throwExceptionIfNotExists = false)
{string errorMsg = null;try{if (sourceInstance == null || string.IsNullOrWhiteSpace(targetPropertyName)){errorMsg = $"Source object is null or property name is null or whitespace. '{targetPropertyName}'";Log.Warn(errorMsg);if (throwExceptionIfNotExists)throw new ArgumentException(errorMsg);elsereturn default(T);}Type returnType = typeof(T);Type sourceType = sourceInstance.GetType();PropertyInfo propertyInfo = sourceType.GetProperty(targetPropertyName, returnType);if (propertyInfo == null){errorMsg = $"Property name '{targetPropertyName}' of type '{returnType}' not found for source object of type '{sourceType}'";Log.Warn(errorMsg);if (throwExceptionIfNotExists)throw new ArgumentException(errorMsg);elsereturn default(T);}return (T)propertyInfo.GetValue(sourceInstance, null);}catch(Exception ex){errorMsg = $"Problem getting property name '{targetPropertyName}' from source instance.";Log.Error(errorMsg, ex);if (throwExceptionIfNotExists)throw;}return default(T);
}

#22楼

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.propertystring[] propertyNameParts = propertyName.Split('.');foreach (string propertyNamePart in propertyNameParts){if (obj == null)    return null;// propertyNamePart could contain reference to specific // element (by index) inside a collectionif (!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 indexint indexStart = propertyNamePart.IndexOf("[")+1;string collectionPropertyName = propertyNamePart.Substring(0, indexStart-1);int collectionElementIndex = Int32.Parse(propertyNamePart.Substring(indexStart, propertyNamePart.Length-indexStart-1));//   get collection objectPropertyInfo pi = obj.GetType().GetProperty(collectionPropertyName);if (pi == null) return null;object unknownCollection = pi.GetValue(obj, null);//   try to process the collection as arrayif (unknownCollection.GetType().IsArray){object[] collectionAsArray = unknownCollection as object[];obj = collectionAsArray[collectionElementIndex];}else{//   try to process the collection as IListSystem.Collections.IList collectionAsList = unknownCollection as System.Collections.IList;if (collectionAsList != null){obj = collectionAsList[collectionElementIndex];}else{// ??? Unsupported collection type}}}}return obj;}

使用C#中的反射从字符串获取属性值相关推荐

  1. Spring Boot 项目中Java对象的字符串类型属性值转换为JSON对象的布尔类型键值的解决方法及过程

    文章目录 场景描述 示例说明 解决历程 @JsonFormat是否能解决问题? 万能方案-调试 替代方案 补充知识 Java对象与JSON对象的序列化与反序列化 相关注解说明 后记 场景描述 在Spr ...

  2. java8 方法引用详解_Java8中如何通过方法引用获取属性名详解

    前言 在我们开发过程中常常有一个需求,就是要知道实体类中Getter方法对应的属性名称(Field Name),例如实体类属性到数据库字段的映射,我们常常是硬编码指定 属性名,这种硬编码有两个缺点. ...

  3. struts2原理分析之反射技术动态获取属性

    反射技术动态获取属性 知道struts2的流程的乡亲们都知道.struts2采用了动态获取属性的方法, 将表单里的数据传给了Action. 例如; 在struts2里有如下配置文件 <actio ...

  4. java 反射根据属性名获取属性值

    一.背景 在使用三方sdk的时候如果三方提供的api满足不了我们的需求,这时候就需要通过阅读三方sdk的代码,并通过反射来实现我们的需求. 二.根据属性名获取属性值 1.考虑安全访问范围内的属性,没有 ...

  5. java 操作属性值_java反射机制根据属性名获取属性值的操作

    一.考虑安全访问范围内的属性,没有权限访问到的属性不读取 /** * 根据属性名获取属性值 * * @param fieldName * @param object * @return */ priv ...

  6. java中遍历实体类,获取属性名和属性值

    方式一(实体类): //java中遍历实体类,获取属性名和属性值public static void testReflect(Object model) throws Exception{for (F ...

  7. java通过属性名获取属性值_java反射机制根据属性名获取属性值的操作

    java反射机制根据属性名获取属性值的操作,属性,对象,反射,访问权限,还可以 java反射机制根据属性名获取属性值的操作 易采站长站,站长之家为您整理了java反射机制根据属性名获取属性值的操作的相 ...

  8. java 反射机制--根据属性名获取属性值

    1.考虑安全访问范围内的属性,没有权限访问到的属性不读取 [java] view plaincopy /** * 根据属性名获取属性值 * * @param fieldName * @param ob ...

  9. java dom4 引入_java – 使用dom4j从节点获取属性值

    我的 XML结构类似于下面的示例.我正在尝试使用dom4j从XML中获取属性值. 目前,节点使用以下代码存储到List中: public List getFoo() { String FOO_XPAT ...

最新文章

  1. error 图片,加载错误-》实用笔记
  2. java三大集合_java中三大集合框架
  3. python3 计时性能测试 %timeit %%timeit
  4. could not insert into NHibernate数据库问题解决
  5. c 用mysql导出xls文件怎么打开_mysql——xls表格的导出和导入(重点)
  6. 在印度8年的华为工程师,有很多话想说。
  7. 手把手教你全家桶之React(一)
  8. 【操作系统】多线程与多任务的比较
  9. 续昨天的文章,在火山图标记基因名字
  10. 为 ASP.NET 创建缓存配置对象[转载]
  11. Web---演示Servlet的相关类、下载技术、线程问题、自定义404页面
  12. 绝对路径、相对路径详解
  13. 航空公司VIP客户查询
  14. 269个JavaScript工具函数,助你提升工作效率(2)
  15. 国内景色最震撼的9座雪山
  16. 终于稀里糊涂完成了模仿天猫整站ssm
  17. Mezzanine入门
  18. CSV文件批量合并/转XLSX(无需任何软件,傻瓜式操作)
  19. STM32F103实现激光测距传感器测距WT-VL53L0 L1
  20. 提高安卓源码编译速度

热门文章

  1. 第二章 Javac编译原理
  2. IBM AIX创建lv
  3. Educational Codeforces Round 39 A Partition
  4. 类 kotlin(13)
  5. 如何去掉WordPress分类目录url链接中的category,如何处理生成的作者链接
  6. MySql(16)——Spring data jpa mysql 乐观锁 与 AtomicInteger
  7. 疯狂Java学习笔记(72)-----------大话程序猿面试
  8. 移动端html头部meta标签的含义
  9. C++ Regsvr32订购具体解释
  10. jQuery知识(转)