興味本位で質問します。
題名通り、以下の様にリフレクションを使って強制的にFinalizeを呼び出したらどうなるでしょうか?
C#
1var mi = obj.GetType().GetMethod( 2 "Finalize", 3 BindingFlags.NonPublic | 4 BindingFlags.InvokeMethod | 5 BindingFlags.Instance); 6mi.Invoke(obj, null); 7GC.SuppressFinalize(obj);
例えば以下の様なプログラムを実行してもエラーが発生しませんでした。
C#
1using System; 2using System.Reflection; 3 4namespace Test 5{ 6 /// <summary> 7 /// このアプリケーションのメインクラスです。 8 /// </summary> 9 public static class Program 10 { 11 /// <summary> 12 /// このアプリケーションのエントリポイントです。 13 /// </summary> 14 /// <param name="args">コマンドライン引数を取得します。</param> 15 /// <returns>OSに実行結果を表す数値を返します。</returns> 16 [STAThread()] 17 public static int Main(params string[] args) 18 { 19 // 普通のオブジェクトを削除する 20 object a = new object(); 21 Console.WriteLine("Delete前(a):" + a); 22 Delete(a); 23 GC.Collect(); // これを呼び出してメモリから完全に削除する 24 Console.WriteLine("Delete後(a):" + a); 25 26 // 簡易的なオブジェクトを削除する 27 Data b = new Data("Hello, World!!"); 28 Console.WriteLine("Delete前(b.Text):" + b.Text); 29 Delete(b); 30 GC.Collect(); // これを呼び出してメモリから完全に削除する 31 Console.WriteLine("Delete後(b.Text):" + b.Text); 32 33 // バイト配列を削除する 34 byte[] c = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 35 Console.WriteLine("Delete前(c):" + string.Join(",", c)); 36 Delete(c); 37 GC.Collect(); // これを呼び出してメモリから完全に削除する 38 Console.WriteLine("Delete後(c):" + string.Join(",", c)); 39 40 // バイト配列を保持したオブジェクトを削除する 41 Data2 d = new Data2(9, 8, 7, 6, 5, 4, 3, 2, 1, 0); 42 Console.WriteLine("Delete前(d.Values):" + string.Join(",", d.Values)); 43 Delete(d); 44 GC.Collect(); // これを呼び出してメモリから完全に削除する 45 Console.WriteLine("Delete後(d.Values):" + string.Join(",", d.Values)); 46 47 Console.ReadKey(true); 48 49 return 0; 50 } 51 52 /// <summary> 53 /// 指定したオブジェクトのデストラクタを呼び出して削除します。 54 /// </summary> 55 /// <param name="obj">削除するオブジェクトです。</param> 56 public static void Delete(object obj) 57 { 58 var mi = obj.GetType().GetMethod( 59 "Finalize", 60 BindingFlags.NonPublic | 61 BindingFlags.InvokeMethod | 62 BindingFlags.Instance); 63 mi.Invoke(obj, null); 64 GC.SuppressFinalize(obj); 65 } 66 67 /// <summary> 68 /// 文字列データを保持するクラスです。 69 /// </summary> 70 public class Data 71 { 72 /// <summary> 73 /// 文字列データです。 74 /// </summary> 75 public string Text { get; set; } 76 77 /// <summary> 78 /// 型'<see cref="Test.Program.Data"/>'の新しいインスタンスを生成します。 79 /// </summary> 80 /// <param name="str">このクラスに保存する文字列です。</param> 81 public Data(string str) { 82 this.Text = str; 83 } 84 85 /// <summary> 86 /// 現在のオブジェクトのリソースを解放します。 87 /// </summary> 88 ~Data() { 89 this.Text = null; 90 Console.WriteLine("デストラクタが呼び出されました。"); 91 } 92 } 93 94 /// <summary> 95 /// バイト配列を保持するクラスです。 96 /// </summary> 97 public class Data2 98 { 99 /// <summary> 100 /// バイト配列です。 101 /// </summary> 102 public byte[] Values { get; set; } 103 104 /// <summary> 105 /// 型'<see cref="Test.Program.Data2"/>'の新しいインスタンスを生成します。 106 /// </summary> 107 /// <param name="values">このクラスに保存するバイト配列です。</param> 108 public Data2(params byte[] values) { 109 this.Values = values; 110 } 111 } 112 } 113}
コンソールには以下の様に表示されました。
Delete前(a):System.Object Delete後(a):System.Object Delete前(b.Text):Hello, World!! デストラクタが呼び出されました。 Delete後(b.Text): Delete前(c):0,1,2,3,4,5,6,7,8,9 Delete後(c):0,1,2,3,4,5,6,7,8,9 Delete前(d.Values):9,8,7,6,5,4,3,2,1,0 Delete後(d.Values):9,8,7,6,5,4,3,2,1,0
強制的にFinalizeを呼び出す事により何か問題が発生するのでしょうか?それとも発生しないのでしょうか?
ご回答お待ちしています。
######環境
OS: Microsoft Windows 10 Creators Update
ランタイム: .NET Framework v4.7
######補足
ここで得られた回答の一部を自分のブログに投稿してもよろしいでしょうか?
引用元は必ず明記します。
回答3件
あなたの回答
tips
プレビュー