2

I met a task in which it is necessary to create an instance of an abstract class using reflection on C#. At the same time, it is forbidden to create heirs.

It is clear that it is forbidden to create such instances, but reflection helps to overcome this. The answers were advised to look in the source codes on the referencesource site, to look for something like an internal call to the constructor through reflection. A hint in the task: need to find a method in the framework that directly deals with calling the constructor and simulate its logic without unnecessary checks. But I can't find. I find how to create instance of abstract class, but without initializing variables.

How can create such an instance so that class variables with values, if they exist are also initialized?

6
  • 2
    If this is a training task, it's a silly one. Commented Feb 15, 2022 at 12:14
  • 1
    Can't be done anyway Commented Feb 15, 2022 at 12:15
  • 2
    An abstract class may have abstract methods (i.e. no implementation). How would your instance handle that? Commented Feb 15, 2022 at 12:19
  • It's a training task. A hint in the task: need to find a method in the framework that directly deals with calling the constructor and simulate its logic without unnecessary checks. But I can't find. I find how to create instance of abstract class, but without initializing variables. Commented Feb 15, 2022 at 12:35
  • 5
    If someone has set a training task which involves using reflection to access an internal method (which does not even exist in recent frameworks) in order to do something that's explicitly prohibited by the C# language, then I have to question whether that someone knows what they're doing... Commented Feb 15, 2022 at 13:32

2 Answers 2

4

As mentioned in the comments, you can call the internal RuntimeTypeHandle.Allocate method to create an instance of an abstact class. Afterwards you can actually call the constructor. Calling an abstract method will throw a System.BadImageFormatException "Bad IL format." This allocate method only exists in the .Net Framework.

abstract class C
{

    public string One;

    public C()
    {
        One = "One";
    }

    public abstract void Abstract();

}

internal class Program
{
    static void Main(string[] args)
    {
        var obj = (C)typeof(RuntimeTypeHandle).GetMethod("Allocate", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { typeof(C) });
        typeof(C).GetConstructor(Type.EmptyTypes).Invoke(obj, new object[0]);

        // outputs "One"
        Console.WriteLine(obj.One);

        // throws BadImageFormatException
        obj.Abstract();
    }
}

Another horrible unsafe option to somehow obtain an instance of an abstract type could be to rewrite an existing objects type information, see: https://github.com/IllidanS4/SharpUtils/blob/master/Unsafe/Chameleon.cs

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you) But if class C have not constructor or have protected constructor, like this: abstract class C { public string One = "One"; public abstract void Abstract(); } or abstract class C { public string One = "One"; protected C() { One = "Two"; } public abstract void Abstract(); } In typeof(C).GetConstructor(Type.EmptyTypes).Invoke(obj, new object[0]); will System.NullReferenceException.
Is there any way for such a case?
@TigraSc You have to modify the GetConstructor call according to your needs. Like specifying the argument types or binding flags to get the constructor you want to call. Have a look in the msdn for all options and overloads: learn.microsoft.com/en-us/dotnet/api/system.type.getconstructor
1

This is not possible, not even with reflection. You'll get a runtime error, as demonstrated in the comments. What is possible, is creating a proxy from an abstract class (e.g. using Castle.Core). But that is still not creating an instance of an abstract class, but dynamically creates an implementation for the abstract members. And then creates an instance of that dynamically created implementation.

6 Comments

I think it possible :) A hint in the task: need to find a method in the framework that directly deals with calling the constructor and simulate its logic without unnecessary checks. But I can't find. I find how to create instance of abstract class, but without initializing variables.
I have had a quite deep insight into the CLR and I'm quite sure that's not the case. That method you search for does not exist. It is possible to create an instance of a value type without calling a constructor, but that is probably not what you are looking for. I'm really interested in how your teacher thinks that works.
Using Allocate I can create an instance of an abstract class, but his variables not initializing with the specified values because constructor not called. I'm really interested too how it may works :) But if we call the constructor of class without checks abstract flag, I think the instance can be created.
Allocate? Which allocate? There's no method with that name in the whole System namespace. Please edit your question and include any piece of code that you already have.
That method is an internal method of an internal class (and, btw no longer exists in .NET Core). Don't use it, unless you know exactly what you're doing. Even if this task was solvable, it is far beyond a C# class exercise. And it makes no sense at all. I can't imagine any reason why you would want to do that.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.