Is there a way to inherit from an internal abstract class in a dynamically generated runtime class (such as via reflection) using .NET Framework 4.0?
Sure you can and you don't need reflection for that. The inherited class just needs to be in the same assembly :)
You can also setup friendship between assemblies: http://msdn.microsoft.com/en-us/library/0tke9fxk%28v=VS.100%29.aspx, which would allow access to internal classes of one assembly. This approach is sometimes useful in creating Unit-Test assemblies that need internal access to tested assemblies
Out of a general sense of perversity in the face of things that shouldn't be possible, I gave it a go at seeing how far I would get at trying to create a class that inherited from System.CurrentSystemTimeZone
(an internal class in mscorlib). It let's you get as far as creating a TypeBuilder
but when you call CreateType
it throws a TypeLoadException
with the message "Access is denied: 'System.CurrentSystemTimeZone'."
A bit more fiddling as led me to conclude that you could create an assembly dynamically which had the strong name that identified it as a friend assembly of the assembly in which the internal type is defined. But then, in that case you could just code class Foo : CurrentSystemTimeZone
anyway, with no trickery being left.
Anyway, the code as far as the line which throws is below, just in case anyone is in the mood for trying some even more perverse variant on the idea, and wants a starting point:
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
namespace ReflectPerversely
{
class SuicidallyWrong
{
private static ModuleBuilder mb;
public static Assembly ResolveEvent(Object sender, ResolveEventArgs args)
{
return mb.Assembly;
}
public static void Main(string[] args)
{
Assembly sys = Assembly.GetAssembly(typeof(string));
Type ic = sys.GetType("System.CurrentSystemTimeZone",true);
AssemblyName an = new AssemblyName();
an.Name = "CheatingInternal";
AssemblyBuilder ab = Thread.GetDomain().DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
mb = ab.DefineDynamicModule("Mod", "CheatingInternal.dll");
AppDomain currentDom = Thread.GetDomain();
currentDom.TypeResolve += ResolveEvent;
TypeBuilder tb = mb.DefineType("Cheat", TypeAttributes.NotPublic | TypeAttributes.Class, ic);
Type cheatType = tb.CreateType();
}
}
}
You can't. You can use types that aren't public using Assembly.GetType()
, but you can't inherit from them. Jon Skeet explains in this article why it is generally a bad idea to access non-public members, and answers your question more in-depth than I could.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With