c# 別クラスのPrivateメソッドを呼び出す方法
こんにちは。開発一部の建部です。
この記事は、公開されていないクラスのPrivateメソッドを呼び出す例をいくつか例示します。
例では実行ファイルでの実装となっていますが、MS-Testなどのテストフレームにも適用でき、
戻り値取得もできるので
Privateなメソッドのユニットテストにも応用できます。
なお、Privateメソッドをユニットテストする意義については、別議論とします。
(VS2022では右クリック→単体テスト作成でも拒否されますし、、、)
やっている事は、
- ReflectionによるPrivateメソッド名の文字特定 →エディタのメソッド名補完機能でも候補に出てこないメソッドが指定できます。
- InvokeによるPrivateメソッドの実行および、その引数指定方法
の2点です。
ファイル構成は
ファイル名 | 説明 | メモ |
---|---|---|
Program.cs | 実行ファイルのエントリポイント | |
TestClass01.cs | 対象クラスのメソッド呼び出し処理 | ※ここで色々やってます |
TargetClass01.cs | 呼び出されるメソッド群 |
です。
Program.cs
using System;
namespace PrivateMethodTest
{
/// <summary>
/// 実行ファイルのエントリ
/// </summary>
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, PrivateMethodTest");
//
TestClass01 testc = new TestClass01();
}
}
}
TestClass01.cs
using System.Reflection;
namespace PrivateMethodTest
{
/// <summary>
/// 対象クラスのメソッド呼び出しクラス
/// </summary>
public class TestClass01
{
/// <summary>
/// コンストラクタ
/// </summary>
public TestClass01()
{
Console.WriteLine("Hello, TestClass01");
//
bool result = TestMethod01();
}
/// <summary>
/// 対象クラスのメソッド呼び出し処理
/// </summary>
/// <returns></returns>
public bool TestMethod01()
{
Console.WriteLine("TestClass01-TestMethod01");
TargetClass01 targetc01 = new TargetClass01();
// Publicなメソッドの呼び出し
int? result = targetc01.PublicMethod01();
// Privateなメソッドの呼び出し
MethodInfo? minfo = targetc01.GetType().GetMethod("PrivateMethod01", BindingFlags.Instance | BindingFlags.NonPublic);
if (minfo != null)
{
Console.WriteLine("PrivateMethod01={0}", (int?)minfo.Invoke(targetc01, null));
}
// Privateな引数付きメソッドの呼び出し
minfo = targetc01.GetType().GetMethod("PrivateMethod02", BindingFlags.Instance | BindingFlags.NonPublic);
if (minfo != null)
{
Console.WriteLine("PrivateMethod02={0}", (int?)minfo.Invoke(targetc01, new object[]{ 2, 3 }));
}
// 事前にPublicなクラスメンバに値をセットしてPrivateなメソッドの呼び出し
targetc01.Property01 = 5;
targetc01.Property02 = 3;
minfo = targetc01.GetType().GetMethod("PrivateMethod03", BindingFlags.Instance | BindingFlags.NonPublic);
if (minfo != null)
{
Console.WriteLine("PrivateMethod03={0}", (int?)minfo.Invoke(targetc01, null));
}
return true;
}
}
}
TargetClass01.cs
namespace PrivateMethodTest
{
/// <summary>
/// 呼び出された衣装クラス
/// </summary>
public class TargetClass01
{
public int Property01 = 0;
public int Property02 = 0;
/// <summary>
/// コンストラクタ
/// </summary>
public TargetClass01()
{
Console.WriteLine("Hello, TargetClass01");
}
/// <summary>
/// 呼び出される処理01
/// </summary>
/// <returns></returns>
public int PublicMethod01()
{
Console.WriteLine("TargetClass01-PublicMethod01");
return -1;
}
/// <summary>
/// 呼び出される処理02
/// </summary>
/// <returns></returns>
private int PrivateMethod01()
{
Console.WriteLine("TargetClass01-PrivateMethod01");
return 0;
}
/// <summary>
/// 呼び出される処理03
/// </summary>
/// <returns></returns>
private int PrivateMethod02(int arg01, int arg02)
{
Console.WriteLine("TargetClass01-PrivateMethod02");
return arg01 - arg02;
}
/// <summary>
/// 呼び出される処理04
/// </summary>
/// <returns></returns>
private int PrivateMethod03()
{
Console.WriteLine("TargetClass01-PrivateMethod03");
return Property01 + Property02;
}
}
}
例は.net9.0のVSCodeでの実行を確認しております。