ped*_*des 860 c# reflection
我正在尝试使用我的代码中的Reflection 1示例实现数据转换.
该GetSourceValue函数有一个比较各种类型的开关,但我想删除这些类型和属性,并GetSourceValue只使用一个字符串作为参数获取属性的值.我想在字符串中传递一个类和属性并解析属性的值.
这可能吗?
Ed *_* S. 1664
public static object GetPropValue(object src, string propName)
{
return src.GetType().GetProperty(propName).GetValue(src, null);
}
Run Code Online (Sandbox Code Playgroud)
当然,你会想要添加验证和诸如此类的东西,但这就是它的要点.
jhe*_*ngs 202
这样的事情怎么样:
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;
}
Run Code Online (Sandbox Code Playgroud)
这将允许您使用单个字符串下降到属性,如下所示:
DateTime now = DateTime.Now;
int min = GetPropValue<int>(now, "TimeOfDay.Minutes");
int hrs = now.GetPropValue<int>("TimeOfDay.Hours");
Run Code Online (Sandbox Code Playgroud)
您可以将这些方法用作静态方法或扩展.
Edu*_*omo 64
添加到任何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; }
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用as:
Foo f = new Foo();
// Set
f["Bar"] = "asdf";
// Get
string s = (string)f["Bar"];
Run Code Online (Sandbox Code Playgroud)
Fre*_*dou 43
怎么样使用CallByName的的Microsoft.VisualBasic命名空间(Microsoft.VisualBasic.dll)?它使用反射来获取普通对象,COM对象甚至动态对象的属性,字段和方法.
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;
Run Code Online (Sandbox Code Playgroud)
然后
Versioned.CallByName(this, "method/function/prop name", CallType.Get).ToString();
Run Code Online (Sandbox Code Playgroud)
小智 27
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;
}
Run Code Online (Sandbox Code Playgroud)
tes*_*ing 12
如果我使用Ed S.的代码,我会得到
由于其保护级别,'ReflectionExtensions.GetProperty(Type,string)'无法访问
似乎GetProperty()在Xamarin.Forms中没有.TargetFrameworkProfile是Profile7在我的便携式类库(.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);
}
Run Code Online (Sandbox Code Playgroud)
Rub*_*ias 10
关于嵌套属性讨论,如果使用DataBinder.Eval Method (Object, String)如下所示,可以避免所有反射内容:
var value = DataBinder.Eval(DateTime.Now, "TimeOfDay.Hours");
Run Code Online (Sandbox Code Playgroud)
当然,您需要添加对System.Web程序集的引用,但这可能不是什么大问题.
以下方法非常适合我:
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); }
}
}
Run Code Online (Sandbox Code Playgroud)
获取属性值:
MyClass t1 = new MyClass();
...
string value = t1["prop1"].ToString();
Run Code Online (Sandbox Code Playgroud)
要设置属性值:
t1["prop1"] = value;
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
这是一种在列表中获取所有属性及其值的方法。
调用方法在.NET Standard中发生了变化(截至1.6).我们也可以使用C#6的null条件运算符.
using System.Reflection;
public static object GetPropValue(object src, string propName)
{
return src.GetType().GetRuntimeProperty(propName)?.GetValue(src);
}
Run Code Online (Sandbox Code Playgroud)
使用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;
}
Run Code Online (Sandbox Code Playgroud)
获取对象的 Location 属性效果很好
Label1.Text = GetObjProperty(button1, "Location").ToString();
Run Code Online (Sandbox Code Playgroud)
我们将得到 Location :{X=71,Y=27} 我们也可以以同样的方式返回 location.X 或 location.Y 。
小智 5
public class YourClass
{
//Add below line in your class
public 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"];
Run Code Online (Sandbox Code Playgroud)