Search code examples
c#performancereflectioninstantiationreflection.emit

Using Emit IL with internal classes?


I have a base class which has an embedded List that can be used by all child classes to return a sorted collection.

I had been using Activator.CreateInstance(), but this is TERRBILY slow compared to a simple new() function.

I found a way to use Emit IL to do this nearly as fast as new(), but if my classes aren't public, I get a MethodAccessException error. This seems to be common.

Is there a way around this?

Code to generate classes here: http://codeblocks.codeplex.com/wikipage?title=FasterActivator%20Sample

Code being used with the above here:

public static List<T> SortedCollection<T>(SPListItemCollection items, ListSortType sortType, List<Vote> votes) where T : IVotable
{
    var returnlist = new List<T>();  
    var functionCreator = FastActivator.GenerateFunc<Func<SPListItem, List<Vote>, T>>();
    for (int i = 0; i < items.Count; i++) { returnlist.Add(functionCreator(items[i], votes)); }

    //Old code here
    //Type genericType = typeof(T);
    //for (int i = 0; i < items.Count; i++) { returnlist.Add((T)Activator.CreateInstance(genericType, new object[] { items[i], votes })); }

    switch (sortType)
    {
        case ListSortType.Hot:
            returnlist.Sort((p1, p2) => p2.HotScore.CompareTo(p1.HotScore));
            break;
        case ListSortType.Top:
            returnlist.Sort((p1, p2) => p2.VoteTotal.CompareTo(p1.VoteTotal));
            break;
        case ListSortType.Recent:
            returnlist.Sort((p1, p2) => p2.CreatedDate.CompareTo(p1.CreatedDate));
            break;
        }
        return returnlist;
    }

    //Usage
    //Post : BaseClass which has above method
    return Post.SortedCollection<Post>(listItems,sortType,votes);

Solution

  • You can use the DynamicMethod Constructor (String, Type, Type[], Type) method to generate a method associated with the class who's members you want access to.

    The generated method will have full access to all members in the type you associate it with, and all internal methods and members the class would have access to in its module.