ich mit den anderen Kommentaren zustimmen, dass dies nicht die Produktion Code sein sollte, sondern aus Spaß es sicherlich getan werden kann:
public static T CreateAbstractInstance<T>() where T : class =>
(T)Activator.CreateInstance(
Thread.GetDomain()
.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Run)
.DefineDynamicModule("DynamicModule")
.DefineType("DynamicType", TypeAttributes.Public | TypeAttributes.Class, typeof(T))
.CreateType());
private static TResult AbstractInvoke<TClass, TResult>(string methodName) where TClass : class
{
var method = typeof(TClass).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
var elegate = method.CreateDelegate(typeof(Func<BaseClass, TResult>));
return (TResult)elegate.DynamicInvoke(CreateAbstractInstance<TClass>());
}
private static void Main()
{
var result = AbstractInvoke<BaseClass, int>("getValue");
Console.WriteLine(result);
}
Es gibt wohl einige Methode, den Compiler zu betrügen und sie aufrufen, ohne auch nur die Schaffung eine Instanz, aber ich wurde zu viele Visual Studio Abstürze, um weiter zu untersuchen, andere Methoden. Ausdrücke scheinen nirgendwohin zu führen, wie am Ende des Tages, es musste immer noch gültigen Code erzeugen, also keine Möglichkeit, einen Ausdruck in ein ungültiges Lambda zu verwandeln.
Wenn Sie eine Singleton-Instanz von CreateAbstractInstance
wiederverwenden, sollten Sie keine Overheads mehr haben, nachdem das erste Objekt erstellt wurde (neben Reflection-Verwendung, wenn Sie nicht öffentliche Methoden aufrufen).
Ich dachte, ich könnte dies auch auf die Antwort hinzufügen:
ich den Kommentar bemerken darüber in einem Unit-Test verwendet wird; wenn Sie Moq verwenden (und wahrscheinlich die meisten der Anständigen Frameworks), können Sie dies tun:
var bc = new Mock<BaseClass>().Object;
// Invoke whatever you want on `bc` with reflection or not.
Obwohl sich bewusst sein, dass, wenn die Methode virtual
ist es automatisch außer Kraft setzen, so dass Sie nicht erhalten Standard die Logik der Basisklasse, aber es kann gelöst werden, den Schein einzurichten.
Wenn Sie eine Instanz erstellen müssen, markieren Sie die Klasse nicht als abstrakt. Sie können immer noch davon erben, solange es nicht als versiegelt markiert ist. So abstrakt funktioniert das, man kann nie eine direkte Instanz einer abstrakten Klasse schaffen ... überhaupt. Es gibt keinen Weg dahin. – Igor
Aus welchem Grund auch immer Sie dies tun, ist es wahrscheinlich die falsche Art, es zu tun. Sie können eine Methode für eine abstrakte Klasse nicht ausführen, es sei denn, statische Reflexion würde Sie nicht dazu bringen, dies zu tun. –
Normalerweise erstelle ich keine Instanz von BaseClass. Aber ich brauche einen Rückgabewert von getValue beim Testen. Soll ich die abstrakte Klasse nur für das Testen in die Standardklasse ändern? – blz