views:

2695

answers:

6

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 anything using reflection. But I've seen some strange things...

+1  A: 

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.

MagicKat
That's the only way it would make sense. For the work involved, how the hell could anyone justify that?? It's just crazy.
Kilhoffer
you CAN'T legitimately justify it.
MagicKat
+1  A: 

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.

Rob Walker
+4  A: 

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.

Orion Edwards
I have seen an example where someone patched the clr itself. Do a search on Dinis Cruz and OWASP and you should find it
alexmac
crikey. That's hardcore
Orion Edwards
Security flaws where the attacker is stronger than the security system are not flaws. "I broke into your building by replacing all the locks with identical ones, except they respond to Bluetooth commands from my cell phone." The Bluetooth attack is irrelevant compared to your removal of my locks!
Jacob
Amen, Jacob. Reminds me of an article I read that claimed Windows had a security flaw where if you booted a machine from your own device you could get into other users' folders on the windows hard drive. The author wasn't happy with Microsoft's response: "You can't expect security when you allow users unrestricted physical access to the computer."
StriplingWarrior
+2  A: 

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();
   }
}
dalle
A: 

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)
        {
        }
    }
A: 

The last post I made is the only way, even using reflection won't do it. FYI