C# 使用反射(或其他方式)获取成员对象
我希望能够通过名称访问属性或类的成员。如果这是一处房产,我很好:C# 使用反射(或其他方式)获取成员对象,c#,reflection,C#,Reflection,我希望能够通过名称访问属性或类的成员。如果这是一处房产,我很好: PropertyInfo prop = object.GetType().GetProperty(propertyName); object propValue = prop.GetValue(object, null); 如果它是一个成员/字段,事情似乎有点棘手。在研究了GetMember并尝试了一系列不同的东西之后,我想不出如何像从GetProperty返回对象(如果它是一个属性)一样获取对该对象的引用 另一个问题是
PropertyInfo prop = object.GetType().GetProperty(propertyName);
object propValue = prop.GetValue(object, null);
如果它是一个成员/字段,事情似乎有点棘手。在研究了GetMember
并尝试了一系列不同的东西之后,我想不出如何像从GetProperty
返回对象(如果它是一个属性)一样获取对该对象的引用
另一个问题是,这是实现这一目标的正确方法吗?在阅读关于反思的文章时,它似乎有很多开销。这仅仅是相对于不使用反射而言的吗?或者它是否足够重要,以至于我应该在开发一些将大量使用反射的东西时三思而后行?如果有的话,我有什么替代方法来获得对一个类成员的名称引用
谢谢你的洞察力。如果有什么不同,我的目标是能够序列化任意命名的属性或类的成员。如果要检索字段,可以使用而不是GetProperty
FieldInfo field = object.GetType().GetField(fieldName);
object fieldValue = field.GetValue(Context.Parent);
或者,我应该三思而后行,开发一些能够大量实现这一点的东西,这是否足够重要?如果有的话,我有什么选择来获得对一个类成员的名称引用
这肯定是昂贵的,但我会分析它,以确定您是否会有性能问题
另一个主要选项是自己构建某种形式的字典,将“名称”映射到值。这可以是直接映射到值的字典,也可以是映射到检索值的委托的字典。这样做的好处在于,可以使它以相同的方式处理属性或字段,但每个类都需要创建映射。(但是,这可能通过在构建时进行反射来实现。)
如果有什么不同,我的目标是能够序列化任意命名属性或类的成员
我建议在滚动您自己的版本之前查看内置的…如果要检索字段,可以使用而不是GetProperty
FieldInfo field = object.GetType().GetField(fieldName);
object fieldValue = field.GetValue(Context.Parent);
或者,我应该三思而后行,开发一些能够大量实现这一点的东西,这是否足够重要?如果有的话,我有什么选择来获得对一个类成员的名称引用
这肯定是昂贵的,但我会分析它,以确定您是否会有性能问题
另一个主要选项是自己构建某种形式的字典,将“名称”映射到值。这可以是直接映射到值的字典,也可以是映射到检索值的委托的字典。这样做的好处在于,可以使它以相同的方式处理属性或字段,但每个类都需要创建映射。(但是,这可能通过在构建时进行反射来实现。)
如果有什么不同,我的目标是能够序列化任意命名属性或类的成员
我建议您在推出自己的版本之前先查看内置版本…如果您使用的是C#4.0(与.NET Framework 4.0和Visual Studio 2010一起发布),那么新的动态
关键字将简化代码中的内容:
dynamic myValue = anyObject;
string name = myValue.myField; // Resolved at runtime, not compile-time
bool result = myValue.myBooleanMethod(1, 2, 3); // Ditto
我的理解是,这与使用反射和测试compatiblePropertyInfo
/MethodInfo
/等的存在性差不多,然后调用它们,因此性能仍然是一个问题,但它肯定更具可读性。如果您使用的是C#4.0(与.NET Framework 4.0和Visual Studio 2010一起发布),有一个新的dynamic
关键字可以简化代码中的内容:
dynamic myValue = anyObject;
string name = myValue.myField; // Resolved at runtime, not compile-time
bool result = myValue.myBooleanMethod(1, 2, 3); // Ditto
我的理解是,这与使用反射和测试兼容的
属性info
/MethodInfo
/等的存在差不多,然后调用它们,所以性能仍然是一个问题,但它肯定更具可读性欢迎光临
public static ConcurrentDictionary<Tuple<Type, string>,
Func<object, object[], object>> ReflectionCache
{
get
{
if (_ReflectionCache==null) {
_ReflectionCache = new ConcurrentDictionary<Tuple<Type, string>,
Func<object, object[], object>>();
}
return _ReflectionCache;
}
} private static ConcurrentDictionary<Tuple<Type, string>,
Func<object, object[], object>> _ReflectionCache = null;
public static object GetCachedProperty(object obj, string name)
{
Func<object,object[],object> del;
if (!ReflectionCache.TryGetValue(Tuple.Create<Type,string>(obj.GetType(),
name), out del)) {
MemberInfo memberInfo =
(MemberInfo)obj.GetType().GetMember(name).GetValue(0);
PropertyInfo prop = null;
FieldInfo fld = null;
switch(memberInfo.MemberType) {
case MemberTypes.Field:
fld = obj.GetType().GetField(name);
break;
case MemberTypes.Property:
prop = obj.GetType().GetProperty(name);
break;
}
if (prop == null && fld == null)
{
throw new Exception("No property or field named '" + name
+ "' could be found in the context parent.");
}
if (prop!=null) {
prop= obj.GetType().GetProperty(name);
del = prop.GetValue;
} else {
fld = obj.GetType().GetField(name);
del = delegate(object cls,object[] index) {
return fld.GetValue(cls);
};
}
ReflectionCache[Tuple.Create<Type,string>(obj.GetType(),name)]=del;
}
return(del(obj,null));
}
公共静态ConcurrentDictionary ReflectionCache
{
收到
{
if(_ReflectionCache==null){
_ReflectionCache=新的ConcurrentDictionary();
}
return\u ReflectionCache;
}
}私有静态ConcurrentDictionary _ReflectionCache=null;
公共静态对象GetCachedProperty(对象对象,字符串名称)
{
Func del;
如果(!ReflectionCache.TryGetValue)(Tuple.Create(obj.GetType()),
姓名),不包括姓名){
MemberInfo MemberInfo=
(MemberInfo)obj.GetType().GetMember(名称).GetValue(0);
PropertyInfo prop=null;
FieldInfo fld=null;
开关(memberInfo.MemberType){
案例成员类型。字段:
fld=obj.GetType().GetField(名称);
打破
案例成员类型。属性:
prop=obj.GetType().GetProperty(名称);
打破
}
if(prop==null&&fld==null)
{
抛出新异常(“没有名为“”的属性或字段+名称
+“'可以在父上下文中找到。”);
}
如果(prop!=null){
prop=obj.GetType().GetProperty(名称);
del=prop.GetValue;
}否则{
fld=obj.GetType().GetField(名称);
del=委托(对象cls,对象[]索引){
返回fld.GetValue(cls);
};
}
ReflectionCache[Tuple.Create(obj.GetType(),name)]=del;
}
返回(del(obj,null));
}
我为缓存提出的建议,欢迎评论
public static ConcurrentDictionary<Tuple<Type, string>,
Func<object, object[], object>> ReflectionCache
{
get
{
if (_ReflectionCache==null) {
_ReflectionCache = new ConcurrentDictionary<Tuple<Type, string>,
Func<object, object[], object>>();
}
return _ReflectionCache;
}
} private static ConcurrentDictionary<Tuple<Type, string>,
Func<object, object[], object>> _ReflectionCache = null;
public static object GetCachedProperty(object obj, string name)
{
Func<object,object[],object> del;
if (!ReflectionCache.TryGetValue(Tuple.Create<Type,string>(obj.GetType(),
name), out del)) {
MemberInfo memberInfo =
(MemberInfo)obj.GetType().GetMember(name).GetValue(0);
PropertyInfo prop = null;
FieldInfo fld = null;
switch(memberInfo.MemberType) {
case MemberTypes.Field:
fld = obj.GetType().GetField(name);
break;
case MemberTypes.Property:
prop = obj.GetType().GetProperty(name);
break;
}
if (prop == null && fld == null)
{
throw new Exception("No property or field named '" + name
+ "' could be found in the context parent.");
}
if (prop!=null) {
prop= obj.GetType().GetProperty(name);
del = prop.GetValue;
} else {
fld = obj.GetType().GetField(name);
del = delegate(object cls,object[] index) {
return fld.GetValue(cls);
};
}
ReflectionCache[Tuple.Create<Type,string>(obj.GetType(),name)]=del;
}
return(del(obj,null));
}
公共静态ConcurrentDictionary ReflectionCache
{
收到
{
如果(_ReflectionCache==