How can you inherit from a sealed class using reflection in .Net?

后端 未结 5 2036
青春惊慌失措
青春惊慌失措 2021-01-07 18:19

Before you start firing at me, I\'m NOT looking to do this, but someone in another post said it was possible. How is it possible? I\'ve never heard of inheriting from anythi

相关标签:
5条回答
  • 2021-01-07 19:06

    It MIGHT (would increase the size if I could). According to the guys on freenode, it would involved modifying the byte code, using Reflection.Emit, and handing the JIT a new set of byte code.

    Not that I KNOW how ... it was just what they thought.

    0 讨论(0)
  • 2021-01-07 19:06

    Create a new class called GenericKeyValueBase

    put this in it

      public class GenericKeyValueBase<TKey,TValue>
        {
            public TKey Key;
            public TValue Value;
    
            public GenericKeyValueBase(TKey ItemKey, TValue ItemValue)
            {
                Key = ItemKey;
                Value = ItemValue;
            }
        }
    

    And inherit from that plus you can add additional extension methods for Add/Remove (AddAt and RemoveAt) to your new derived class (and make it a collection/dictionary) if you are feeling really cool.

    A simple implentation example where you would use a normal System.Collections.Generic.KeyValuePair for a base, but instead can use the above code

      class GenericCookieItem<TCookieKey, TCookieValue> : GenericKeyValueBase<TCookieKey,TCookieValue>
        {
            public GenericCookieItem(TCookieKey KeyValue, TCookieValue ItemValue) : base(KeyValue, ItemValue)
            {
            }
        }
    
    0 讨论(0)
  • 2021-01-07 19:08

    Without virtual functions to override, there's not much point in subclassing a sealed class.

    If you try write a sealed class with a virtual function in it, you get the following compiler error:

    // error CS0549: 'Seal.GetName()' is a new virtual member in sealed class 'Seal'
    

    However, you can get virtual functions into sealed classes by declaring them in a base class (like this),

    public abstract class Animal
    {
        private readonly string m_name;
    
        public virtual string GetName() { return m_name; }
    
        public Animal( string name )
        { m_name = name; }
    }
    
    public sealed class Seal : Animal
    {
        public Seal( string name ) : base(name) {}
    }
    

    The problem still remains though, I can't see how you could sneak past the compiler to let you declare a subclass. I tried using IronRuby (ruby is the hackiest of all the hackety languages) but even it wouldn't let me.

    The 'sealed' part is embedded into the MSIL, so I'd guess that the CLR itself actually enforces this. You'd have to load the code, dissassemble it, remove the 'sealed' bit, then reassemble it, and load the new version.

    0 讨论(0)
  • 2021-01-07 19:11

    I'm sorry for posting incorrect assumptions in the other thread, I failed to recall correctly. Using the following example, using Reflection.Emit, shows how to derive from another class, but it fails at runtime throwing an TypeLoadException.

    sealed class Sealed
    {
       public int x;
       public int y;
    }
    
    class Program
    {
       static void Main(string[] args)
       {
          AppDomain ad = Thread.GetDomain();
          AssemblyName an = new AssemblyName();
          an.Name = "MyAssembly";
          AssemblyBuilder ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
          ModuleBuilder mb = ab.DefineDynamicModule("MyModule");
          TypeBuilder tb = mb.DefineType("MyType", TypeAttributes.Class, typeof(Sealed));
    
          // Following throws TypeLoadException: Could not load type 'MyType' from
          // assembly 'MyAssembly' because the parent type is sealed.
          Type t = tb.CreateType();
       }
    }
    
    0 讨论(0)
  • 2021-01-07 19:19

    The other poster may have been thinking more along the lines of Reflection.Emit rather than the more usual read-only Reflection APIs.

    However, still isn't possible (at least according to this article). But it is certainly possible to screw somethings up with Reflection.Emit that are not trapped until you try to actually execute the emitted code.

    0 讨论(0)
提交回复
热议问题