【问题标题】:Getting a value by reflection without garbage通过反射获得价值,没有垃圾
【发布时间】:2010-03-04 09:49:27
【问题描述】:

我正在编写一个系统,它要求我获取对象中的属性值,最好使用反射。这个项目是针对 xbox360 的,它在紧凑的框架上运行,因此垃圾收集器很慢 - 这意味着我避免分配是绝对重要的!

我发现这样做的唯一方法是:

Foo Something; //an object I want to get data from
PropertyInfo p; //get this via reflection for the property I want
object value = p.GetGetmethod().Invoke(Something, null);
//Now I have to cast value into a type that it should be

我不喜欢这个有两个原因:

  • 铸造是为陶工准备的,泛型是为程序员准备的
  • 显然,每次我必须获取原始值时都会产生垃圾,并且会被装箱。

是否有一些通用的方法可以从属性中获取值,它不会装箱原语?

编辑::响应乔恩斯的回答,从他的博客中窃取的这段代码不会导致分配,问题已解决:

        String methodName = "IndexOf";
        Type[] argType = new Type[] { typeof(char) };
        String testWord = "TheQuickBrownFoxJumpedOverTheLazyDog";

        MethodInfo method = typeof(string).GetMethod(methodName, argType);

        Func<char, int> converted = (Func<char, int>)Delegate.CreateDelegate
            (typeof(Func<char, int>), testWord, method);

        int count = GC.CollectionCount(0);

        for (int i = 0; i < 10000000; i++)
        {
            int l = converted('l');

            if (GC.CollectionCount(0) != count)
                Console.WriteLine("Collect");
        }

【问题讨论】:

  • 哈哈,我可能会偷你的“陶工”报价;)

标签: c# reflection garbage


【解决方案1】:

另一种方法是使用 Delegate.CreateDelegate 从 getter 方法创建一个委托 - 不过我不知道 Xbox 使用的紧凑框架版本是否支持。

我在Delegate.CreateDelegate 上有一个blog post,您可能会觉得它很有用 - 但同样,您需要看看它有多少适用于 Xbox。

【讨论】:

  • 啊,看起来很有趣,今晚回家后我会在控制台上进行一些调查。出于兴趣,您的协议缓冲区库创建了多少垃圾?
  • @Martin:说实话,我不知道。我们所有构建的值都是不可变的,这自然会导致更多的垃圾——但这真的取决于你如何使用它。
  • 我怀疑 delegate.CreateDelegate 是从其自身内部的盒装原始类型进行转换:/ 看起来我将不得不设计一个新架构 :(
  • 对不起,我之前很着急。创建委托相对昂贵 - 如果可能的话,您应该只对每个属性执行一次。但是,调用它应该非常便宜 - 比通过反射 giong 便宜得多。
  • 好吧,我附加到我的答案的测试分配了,但是我即将将测试更新为稍微不同的东西,它没有分配。匆忙中写得很糟糕。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多