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?
-
4Maybe some background as to what you're trying to achieve and why would help get a useful answer. – Greg B Dec 13 '11 at 22:42
-
1I don't see why this question was closed as "not a real question". I think it is clear what the OP wanted to ask. I admit it is really rather "perverse" (as @John Hanna wrote in his answer), but actually I have a problem (a class that previously was public, was made internal from one version to another of the framework we depends on), that we can "solve" by inheriting from an internal class, if it was possible... – pholpar Jan 29 '18 at 11:31
-
Agreed, this is a valid question and might occur if someone is trying to use a 3rd party library in ways the original creators didn't intend. Not ideal but valid nonetheless. I've nominated it for reopening. – Max Nov 18 '18 at 18:19
-
@Max +1. I ran into this problem when I was trying to customize the behavior of a poorly designed class library (authors didn't put much thought into which classes/methods would be important for inheritors to be accessible/overridable). In my case I could have achieved what I wanted by building a dynamic proxy to an internal class using Reflection.Emit but the runtime didn't like that (TypeLoadException, access is denied...) I couldn't modify the class library so InternalsVisibleTo was out of question. I was almost giving up when I found this: https://github.com/castleproject/Core/issues/402 – Adam Simon Apr 18 '22 at 18:39
3 Answers
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();
}
}
}

- 110,372
- 10
- 146
- 251
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

- 4,644
- 3
- 34
- 46
-
+1 for entertainmet value. But one can't make friendship via reflection, so not really useful for EOG. – Alexei Levenkov Dec 14 '11 at 01:00
-
I interpret "ex." as "for example" so reflection might not be a hard requirement. – surfen Dec 14 '11 at 01:25
-
Good point... I guess @EOG should get -1 for title not matching the question... but I think -2 is too much for this question. – Alexei Levenkov Dec 14 '11 at 01:58
-
You could however add a method to the assembly which has the internal type, in this method you could create a class which inherits and return that class. It seems easier to just add the internals visibility attitude to the assembly though, you can do that pretty much the same way as adding a method and it's lighter. – Jay May 04 '16 at 14:26
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.
-
1
-
@YuriyFaktorovich You can access them, but as far as I know you can not inherit from them. – aevitas Dec 13 '11 at 22:50
-
I'm actually guessing you can using the ILGenerator, but haven't tried it yet. – Yuriy Faktorovich Dec 13 '11 at 22:53