views:

71

answers:

1

I am writing a system which requires me to fetch the values of properties in an object, preferably using reflection. This project is for the xbox360, which runs on the compact framework and thus has a slow garbage collector - this means it's absolutely vital that I avoid allocations!

The only way I have found to do this is:

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

I dislike this for 2 reasons:

  • Casting is for potters, generics is for programmers
  • It obviously creates garbage every time I have to get a primitive value and it gets boxed.

Is there some generic method for getting the value from a property, which will not box primitives?

EDIT:: In response to Jons answer, this code stolen from his blog does not cause allocations, problem solved:

        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");
        }
+1  A: 

One alternative would be to create a delegate from the getter method using Delegate.CreateDelegate - I don't know whether that's supported on the compact framework version used by the Xbox though.

I have a blog post on Delegate.CreateDelegate which you may find useful - but again, you'll need to see how much of it is applicable to the Xbox.

Jon Skeet
Ah, looks interesting, I shall do some investigation on the console when I get home tonight. Out of interest, how much garbage does your protocol buffer library create?
Martin
@Martin: I don't know, to be honest. All our built values are immutable, which naturally leads to a bit more garbage - but it really depends on how you use it.
Jon Skeet
I suspect the delegate.CreateDelegate is doing the cast from a boxed primitive type inside itself :/Looks like I'm gonna have to design a new architecture :(
Martin
@Martin: I see no reason to assume that...
Jon Skeet
Sorry, I was in a rush before. Creating the delegate is relatively expensive - you should only do this once per property, if at all possible. However, calling it should then be *very cheap* - much cheaper than giong via reflection.
Jon Skeet
Well the test I appended to my answer allocated, however I'm about to update the test to something slightly different, which doesn't allocate. It was a badly written test in a hurry.
Martin