私は、これは、生産コードをすべきではないことを他のコメントに同意するが、楽しみのうち、確かに行うことができます。
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);
}
はおそらく、コンパイラをだまして、それを呼び出すために、いくつかの方法があるにも作成することなく、インスタンスが、私はあまりにも多くなっていたVisual Studioは、他の方法の調査を続行するためにクラッシュします。式は今日の終わりにはどこにも出てこないようですが、有効なコードを生成しなければならないので、式を無効なラムダにトリックすることはできません。
シングルトンインスタンスをCreateAbstractInstance
から再利用する場合は、最初のオブジェクトが作成された後にオーバーヘッドを設定しないでください(非公開メソッドを呼び出す場合、リフレクションの使用法の横にある)。
私は、同様の答えにこれを追加するかもしれないと思った:
私はユニットテストでそれを使用してについてのコメントを注意してください。この方法であれば、あなたがで取得することはできませんのでvirtual
それが自動的にそれを上書きすることに注意してますが
var bc = new Mock<BaseClass>().Object;
// Invoke whatever you want on `bc` with reflection or not.
:あなたは部品番号(とまともなフレームワークのおそらく最も)を使用している場合、あなたはこれを行うことができますデフォルトは基本クラスのロジックですが、モックを設定することで解決できます。
インスタンスを作成する必要がある場合は、抽象クラスとしてマークしないでください。封印されていない限り、引き続き継承することができます。それは抽象クラスが直接的なインスタンスを作成することは決してありません。その周りに方法はありません。 – Igor
あなたがこれをやっている理由は、おそらく間違ったやり方です。静的リフレクションではできない限り、抽象クラスでメソッドを実行することはできません。 –
通常、私はBaseClassのインスタンスを作成しません。 しかし、私はテストでgetValueの戻り値が必要です。 抽象クラスをテスト用に標準クラスに変更する必要がありますか? – blz