TypeInitializationException with generic class


Below you can find the runtime error exception detail.

This is when I have a generic class that its method is "sheep'ed", when you try to invoke these method, this exception is thrown.

Attached a simple reproduction project that is the same as the other issue.

Thank you again for your great tool, it is very useful!
System.TypeInitializationException was unhandled
  Message=The type initializer for '<>sac_Fail_3<>JpStatic' threw an exception.
       at Failed.Generics`1.Fail_3()
       at Failed.Programs.Main(String[] args) in c:\Users\alan\Downloads\sheepaspect-85959\Failed\Programs.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.TypeLoadException
       Message=GenericArguments[0], 'T', on 'Failed.Generics`1[T]' violates the constraint of type parameter 'T'.
            at Failed.Generics`1.<>sac_Fail_3<>JpStatic..cctor()

file attachments


awyl wrote Sep 3, 2013 at 9:47 PM

        private static class <>sac_Fail_3<>JpStatic
            public static JointPointBase.StaticPart Instance = JointPointBase.StaticPart.ForMethod(new AdviceInvoker(Generics<T>.<>sac_Around/Failed.Aspects.SampleAspect::LogAroundMethod$Invoke), new AdviceCallback(Generics<T>.<>sac_Fail_3<>JpStatic.Callback), MethodBase.GetMethodFromHandle(methodof(Generics.Fail_3()).MethodHandle, typeof(Generics<T>).TypeHandle));
            private static object Callback(object thisInstance, object target, object[] args)
                return thisInstance.<>sac_Fail_3$TargetMethod();
I figure that it is this part that cause the exception:
new AdviceInvoker(Generics<T>.<>sac_Around/Failed.Aspects.SampleAspect::LogAroundMethod$Invoke)
In AroundWeaverBase.cs -> InitStaticJp()
if I replace this
            il.Append( OpCodes.Ldftn, InvokerMethod.MakeHostInstanceGeneric( thisRef ) );
            il.Append( OpCodes.Newobj, Module.Import( typeof( AdviceInvoker ).GetConstructors()[0] ) );
with this
            il.Append( OpCodes.Ldnull );
Null reference exception will occur when the code call the AdviceInvoker, because it is actually null. So it get pass ctor.

I am still not sure how to fix it. Hope you can take a look.


awyl wrote Sep 5, 2013 at 5:36 PM

Found out more about the issue.

Reference: TEXT

If I remove the generic constraints, it works.

awyl wrote Sep 5, 2013 at 9:48 PM

Not sure if this is the correct fix, but it doesn't throw the generics constraint error after I added this to AroundWeaverBase.cs -> AddGenericParamToJp
var clone = new GenericParameter(param.Name, JpStaticClass);
clone.Attributes = param.Attributes;
foreach ( var cons in param.Constraints ) clone.Constraints.Add( cons );
foreach ( var ca in param.CustomAttributes ) clone.CustomAttributes.Add( ca );
foreach ( var gp in param.GenericParameters ) clone.GenericParameters.Add( gp );
clone.HasDefaultConstructorConstraint = param.HasDefaultConstructorConstraint;
clone.IsContravariant = param.IsContravariant;
clone.IsCovariant = param.IsContravariant;
clone.IsNonVariant = param.IsNonVariant;    

hendryluk wrote Sep 5, 2013 at 11:40 PM

Thanks so much for reporting the bug and for the fix. Sorry it took so long to get back to you. I'll have a look at this.


wrote Dec 19, 2013 at 1:09 AM

VoiceOfWisdom wrote Dec 19, 2013 at 1:12 AM

Any way this could be merged in, and pushed to nuget? I have some generic methods that are giving me heartburn with this.