Unexpected TypeLoadException during Type Creation

We have found some limitations in Reflection.Emit that you cannot emit types that can be compiled in C# compiler. You are unlikely to hit it in daily emit job but if ever you met one:

public class E
{
    public struct N1
    {
        public E e;
    }

    public struct N2
    {
        public N1 n1;
    }

    N2 n2;   
}

There are two partial order functions that must be satisfied for ref.emit type loading to succeed and sometimes there is way to satisfy both rules. The order rules are:

1. All types of all struct fields must be loaded before the type (this one is necessary)
2. All enclosing types of all field types must be loaded before the type (this one is not necessary but is artificially imposed by the ref.emit path through the loader)

For rule 1 the orders are the subset of all orders where N1 is loaded before N2 and N2 is loaded before E which leaves us with only one:

N1 > N2 > E

For rule 2 the partial orders are the subset of all orders where E is loaded before N2 which leaves us with 2:

E > N1 > N2
N1 > E > N2

But there is no intersection of these sets and so no way to create this assembly with ref.emit.

Of course, the early bound loader doesn't have the rule 2 restriction so there is a code path that will work but it is likely too much work to move reflection emit over to that code path. So at least for Whidbey, we will have to live with such restrictions.

However, it is possible that you could try to solve the TypeLoadException by hooking your own type resolver up to the AppDomain's TypeResolve event.

Comments

  • Anonymous
    March 21, 2006
    I found your page from google but i like it so much
  • Anonymous
    June 03, 2006
    i like your website very much but please do get us more information about it
  • Anonymous
    January 06, 2008
    When I started writing vbnc, there weren't many options when it came to deciding which library to