はじめに
今回はPrivateコンストラクタしかないclassを無理やりリフレクションで作成する方法を紹介したいと思います。
public class Hoge { // privateコンストラクタしかないと正攻法だと外から生成できない private Hoge() { } }
やり方
引数がない場合
Activator.CreateInstance
のnonPublic
があるオーバーロードを利用することで実現できます。
public static object? CreateInstance (Type type, bool nonPublic);
// サンプル public class Sample { public static void Main(string[] args) { // NG: var hoge = new Hoge(); // 引数のnonPublicをtrueにするのがキモ var hoge = (Hoge)Activator.CreateInstance(typeof(Hoge), nonPublic: true); hoge.Execute(); } } public class Hoge { // privateコンストラクタしかないと正攻法だと外から生成できない private Hoge() { } public void Execute() => Console.WriteLine("Hello, World!"); }
引数がある場合
コンストラクタに引数がある場合はbindingAttr
とargs
が引数にあるCreateInstance
メソッドを利用します。
public static object? CreateInstance (Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture);
Activator.CreateInstance メソッド (System) | Microsoft Learn
public class Sample { public static void Main(string[] args) { // NG: var hoge = new Hoge("Hello, World", "text2"); // 引数bindingAttrに以下のBindingFlagsを渡し、argsに引数を渡す BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic; var hoge = (Hoge)Activator.CreateInstance(typeof(Hoge), bindingAttr, null, ["Hello, World", "text2"], null); hoge.Execute(); } } public class Hoge { private readonly string _text; // privateコンストラクタしかないと正攻法だと外から生成できない private Hoge(string text, string text2) { _text = text; } public void Execute() => Console.WriteLine(_text); }