WPFで常駐アプリを開発しているのですが、解決方法が分からない警告があり質問させてください。
コポーネントクラスを使ったアプリケーションを作成しています。
App.xml.csの中でコンポーネントクラスを開放する処理を書いているのですが、下記に該当する警告が発生します。
CA1001:破棄可能なフィールドを所有する型は、破棄可能でなければなりません
そもそも、コンポーネントクラスの開放は不要でしょうか?
それとも、コンポーネントクラスの開放は必要で、
AppクラスをIDisposableインターフェイスとして実装して開放できるようにするのが一般的なのでしょうか?
コンポーネントクラスを使うプロジェクトの情報は見つかるのですが、該当の警告の対応方法や開放の方法が見つかりませんでした。
そのため、こちらで質問させていただきました。
参考にしたページ
参考にしたページではコンポーネントクラスの開放しています。
元のソース
プロジェクト内で、NotifyIconWrapper
と言うコンポーネントクラスを作っています。
タスクメニューに表示するアイコンのラッパーです。
アプリケーションを終了する際にコンポーネントクラスを開放します。
開始時にインスタンスを作る処理を記載し忘れておりました。
cs
1namespace SampleProject 2{ 3 /// <summary> 4 /// App.xaml の相互作用ロジック 5 /// </summary> 6 public partial class App : Application, IDisposable 7 { 8 9 /// <summary> 10 /// タスクトレイに表示するアイコンのコンポーネント 11 /// </summary> 12 private NotifyIconWrapper NotifyIconWrapper = new NotifyIconWrapper(); 13 14 /// <summary> 15 /// System.Windows.Application.Exit イベントのラッパー 16 /// </summary> 17 /// <param name="e"></param> 18 protected override void OnExit(ExitEventArgs e) 19 { 20 base.OnExit(e); 21 this.NotifyIconWrapper.Dispose(); 22 } 23 } 24}
Visual Studioのログに表示されるエラー
CA1001: 型'App'は破棄可能なフィールド'notifyIcon'を所有しますが、破棄可能ではありません。
試した事
クイックアクションとリファクタリングを参考に、IDisposable
インターフェイスを実装しました。
cs
1namespace SampleProject 2{ 3 /// <summary> 4 /// App.xaml の相互作用ロジック 5 /// </summary> 6 public partial class App : Application, IDisposable 7 { 8 9 /// <summary> 10 /// タスクトレイに表示するアイコンのコンポーネント 11 /// </summary> 12 private NotifyIconWrapper notifyIcon = new NotifyIconWrapper(); 13 14 public void Dispose() 15 { 16 throw new NotImplementedException(); 17 } 18 19 /// <summary> 20 /// System.Windows.Application.Exit イベントのラッパー 21 /// </summary> 22 /// <param name="e"></param> 23 protected override void OnExit(ExitEventArgs e) 24 { 25 base.OnExit(e); 26 this.notifyIcon.Dispose(); 27 } 28 } 29}
発生したエラー
実装したところ別の警告が発生して、Appクラスそのものを大きく修正しないと解決出来ないエラーが発生しました。
コード | 説明 |
---|---|
CA1065 | Dispose は型 NotImplementedException の例外を作成します。この型のメソッドでは例外を発生させることはできません。この例外インスタンスが発生する可能性がある場合は、例外が発生しないようにこのメソッドのロジックを変更します。 |
CA1063 | 'App' で Dispose(bool) のオーバーライド可能な実装を提供するか、型を sealed としてマークします。Dispose(false) を呼び出す場合は、ネイティブ リソースのみがクリーンアップされます。Dispose(true) を呼び出す場合には、マネージド リソースとネイティブ リソースの両方がクリーンアップされます。 |
CA2000 | 'new App()' が作成したオブジェクトへの参照がすべてスコープ外になる前に、そのオブジェクトの System.IDisposable.Dispose を呼び出してください。 |
CA1063 | 'App.Dispose' を変更し、Dispose(true) を呼び出したのちに現在のオブジェクト インスタンスで GC.SuppressFinalize (Visual Basic の 'this' または 'Me') を呼び出して、結果を戻すようにします。 |
CA1816 | GC.SuppressFinalize(object) を呼び出すように App.Dispose() を変更します。これにより、ファイナライザーを導入する派生型で、その呼び出しのために 'IDisposable' を再実装する必要がなくなります。 |
所見
エラーの解説ページの修正方法が、IDisposableインターフェイスとして実装と書かれている事です。
CA1001:破棄可能なフィールドを所有する型は、破棄可能でなければなりません
IDisposableを追加する理由は、アンマネージリソースを解放することが目的だと知りました。
コンポーネントクラスは.NETフレームワークで管理されているリソースなのでアンマネージリソースではないのではないと思います。
アンマネージとマネージの考え方がそもそも間違っているのかもしれません。
回答2件
あなたの回答
tips
プレビュー