Question

Damkjer on Wed, 09 Jun 2010 20:54:35


The following code generates an exception and I would like to know what I am doing wrong. I thought the RuntimeHelpers.PrepareMethod, was supposed to be able to prepare virtual method?

Thanks

  public class AClass
  {
    protected virtual void Dispose(bool disposing)
    {
    }
  }

  public class BClass<TObject> : AClass
  {
    private TObject instance;

    public BClass() : base()
    {
      instance = default(TObject);

      System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(
        this.GetType().GetMethod("Dispose",
        System.Reflection.BindingFlags.NonPublic |
        System.Reflection.BindingFlags.Instance |
        System.Reflection.BindingFlags.DeclaredOnly).MethodHandle
        );
    }

    protected override void Dispose(bool disposing)
    {
      base.Dispose(disposing);
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // This instantiation works
      BClass<int> bClassInt = new BClass<int>();

      System.Console.WriteLine("Success");

      // The next statement throws a:
      //
      // System.ArgumentException
      //
      // The given generic instantiation was invalid.

      BClass<object> bClassObject = new BClass<object>();

      System.Console.ReadLine();
    }
  }

Replies

Jason Kresowaty on Thu, 10 Jun 2010 01:23:33


There is another overload of PrepareMethod.  The following did not throw an exception.  I really don't have any familiarity with PrepareMethod, so I can't say if this is actually correct or not.  You'll need to research this method some more.

    System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(
      this.GetType().GetMethod("Dispose",
        System.Reflection.BindingFlags.NonPublic |
        System.Reflection.BindingFlags.Instance |
        System.Reflection.BindingFlags.DeclaredOnly).MethodHandle,
      new System.RuntimeTypeHandle[] { typeof(TObject).TypeHandle });

Damkjer on Thu, 10 Jun 2010 04:40:28


Thank you this really did help. I hadn't noticed the overload... I should have. Sorry for that. Sometimes its difficult to see the solution when it lying right in front of you.

Thanks :-)

botanik32 on Wed, 26 Sep 2012 09:11:32


Do not call PrepareMethod if it's abstract or have generic parameters:

if (!method.IsAbstract && !method.ContainsGenericParameters)
{

    System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(method.MethodHandle);

}