Hi,

I noticed that TypeBuilder never throws InvalidOperationException
when CreateType() is invoked twice. It is because of this change:

2004-12-06  Ben Maurer  <[EMAIL PROTECTED]>
        * TypeBuilder.cs (CreateType): Creating a type twice does not
        throw in msft.

Well, this is correct for .NET 2.0.

To see what happens, try attached example.

MSDN documentation (still) says that it will throw the exception.
http://msdn2.microsoft.com/library/y29h8wb9.aspx

So, I think we could make compromised fix for them; just return
already-created type for NET_2_0, and throw exception otherwise.

I also noticed that GetMembers() never throws an exception in
TypeBuilder when there is not created type, but not sure if it
is intended. It might be too naive to fill the differences
between MS one. At least we should be very careful to change them
because mcs heavily depends on them. If it makes sense, I'll
track down more on this matter and file bugs.

For now, to apply this TypeBuilder fix, mcs is also needed to be
fixed (included in the patch).

Atsushi Eno
using System;
using System.Reflection;
using System.Reflection.Emit;

public class Test
{
        public static void Main ()
        {
                AssemblyName an = new AssemblyName ();
                an.Name = "hogeasm";
                AssemblyBuilder ab = 
                        AppDomain.CurrentDomain.DefineDynamicAssembly (an,
                                AssemblyBuilderAccess.Save);
                ModuleBuilder mb = ab.DefineDynamicModule ("hogemod");
                TypeBuilder tb = mb.DefineType ("MyInterface",
                        TypeAttributes.Interface |
                        TypeAttributes.Public |
                        TypeAttributes.Abstract);
                tb.DefineEvent ("MyEvent", EventAttributes.None,
                        typeof (EventHandler));

                Console.WriteLine (tb.CreateType () != tb);
                Console.WriteLine (tb.CreateType () != tb);
        }
}

Index: mcs/class.cs
===================================================================
--- mcs/class.cs        (revision 41656)
+++ mcs/class.cs        (working copy)
@@ -2118,7 +2118,15 @@
 
                        try {
                                caching_flags |= Flags.CloseTypeCreated;
-                               TypeBuilder.CreateType ();
+#if NET_2_0
+                               if (!TypeBuilder.IsCreated ())
+                                       TypeBuilder.CreateType ();
+#else
+                               try {
+                                       TypeBuilder.CreateType ();
+                               } catch (InvalidOperationException) {
+                               }
+#endif
                        } catch (TypeLoadException){
                                //
                                // This is fine, the code still created the type
Index: class/corlib/System.Reflection.Emit/TypeBuilder.cs
===================================================================
--- class/corlib/System.Reflection.Emit/TypeBuilder.cs  (revision 41656)
+++ class/corlib/System.Reflection.Emit/TypeBuilder.cs  (working copy)
@@ -623,7 +623,20 @@
                        return false;
                }
                
-               public Type CreateType() {
+               public Type CreateType ()
+               {
+                       if (created != null)
+#if NET_2_0
+                               return created;
+#else
+                               throw new InvalidOperationException ("Unable to 
change after type has been created.");
+#endif
+
+                       return CreateTypeInternal ();
+               }
+
+               private Type CreateTypeInternal ()
+               {
                        /* handle nesting_type */
                        if (created != null)
                                return created;
@@ -1258,7 +1271,7 @@
                        TypeBuilder datablobtype = DefineNestedType (s,
                                
TypeAttributes.NestedPrivate|TypeAttributes.ExplicitLayout|TypeAttributes.Sealed,
                                pmodule.assemblyb.corlib_value_type, null, 
PackingSize.Size1, size);
-                       datablobtype.CreateType ();
+                       datablobtype.CreateTypeInternal ();
                        return DefineField (name, datablobtype, 
attributes|FieldAttributes.Static|FieldAttributes.HasFieldRVA);
                }
 

Reply via email to