c# - 循环中的高效反射

标签 c# reflection

我在循环中使用反射时遇到性能问题。问题是我用它来重复访问长依赖链末尾的对象。例如,在这样的情况下

class FirstObject 
{
    public SecondObject sO;
}

class SecondObject
{
    public ThirdObject tO;
}

class ThirdObject
{
    public FourthObject fO;
}

class FourthObject
{
    public object neededValue;
}

因为我只对最后一个对象包含的值感兴趣,所以我需要使用 GetProperty().GetValue() 重复遍历整个链

FirstObject -> SecondObject -> ThirdObject -> FourthObject [需要值]

在这种情况下,是否有任何方法(也许是一些 API)可用于缩短链或仅将整个路径保存到 neededValue

澄清

我需要对包含 FirstObjects 的列表执行此操作。我无法重写代码来减少嵌套级别:它是自动生成的。

最佳答案

有一个技巧可以用来代替反射的 GetValue() .肯定更快,但是代码可读性会差很多。

object GetPropertyValue(object obj, string propertyName)
{
    MethodInfo propertyGetter = obj.GetType().GetMethod("get_" + propertyName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
    Func<object> getPropertyValue = (Func<object>)Delegate.CreateDelegate(typeof(Func<object>), obj, propertyGetter);
    return getPropertyValue();
}

这里我们使用了一点“hack”,知道属性 getter 只是一个具有预定义名称的方法:get_<PropertyName>() .

您甚至可以缓存 propertyGetter上面示例中的对象并重用它,如果您的对象层次结构每次都相同的话。


更新

您甚至可以在没有具体对象引用的情况下为属性 getter 创建委托(delegate)。因此,您可以将此委托(delegate)与许多对象(相同类型)一起使用:

Func<ObjectType, object> getPropertyValue = (Func<ObjectType, object>)Delegate.CreateDelegate(typeof(Func<ObjectType, object>), propertyGetter);

ObjectType obj;
var propertyValue = getPropertyValue(obj);

如果缓存 getPropertyValue()委托(delegate),那么性能将明显优于调用 GetValue()方法。

关于c# - 循环中的高效反射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40627007/

相关文章:

c# - 阿兹曼过时了吗?阿兹曼的新替代品是什么?

.net - 在程序中运行外部 C# 文件

java - 检测 Java 反射

c# - InvalidOperationException 连接未关闭。连接的当前状态是打开的

c# - 验证仅包含数字的正则表达式,不应包含空格和字母

C# Web 异常意外的 EOF

c# - 如何获取特定属性的 PropertyInfo?

scala - 如何获取scala特征中所有方法的名称

class - 通过反射将类强制转换为基接口(interface)导致异常

c# - 无法从 'Xamarin.Forms.TextCell' 转换为 'Xamarin.Forms.View'