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