1

CA2000 Dispose objects before losing scope

In method FormMain.barButtonItem1_ItemClick(object, ItemClickEventArgs)

Call System.IDisposable.Dispose on object 'frm' before all references to it are out of scope. Winpro FormMain.cs 32

Method :

private void barButtonItem1_ItemClick(object sender, ItemClickEventArgs e)
{
    FormCustomerList frm = new FormCustomerList();
    frm.MdiParent = this;
    frm.Show();
}

This is not a serious problem, but why is this fired?

I can't use finally frm.Dispose() or using() because form will not be shown.

I have also tried to handle form closing and then dispose but violation is always here.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Carlo
  • 151
  • 1
  • 3
  • 16
  • 1
    Doesn't `Show` block until the form is closed? In that case you can call dispose after. Otherwise, you need to keep a reference around in a member so you can dispose it later. – Lee Jan 22 '14 at 11:39
  • 1
    _"I can't use finally frm.Dispose() or using() because form will not be shown"_ - please show the code where you tried this, as this should just work. – CodeCaster Jan 22 '14 at 11:39
  • 1
    It is a false warning. (In this very specific case). Calling Dispose will destroy the child form.I think that the MDI Container knows how to dispose its childs when you close it. If you search for `CA2000 false positive` you should find thousands links that explain why you get this message (and it is a code-analysys warning, not a compiler warning) – Steve Jan 22 '14 at 11:51
  • @Lee `ShowDialog` blocks. `Show` does not. – BJ Myers Jan 28 '14 at 00:24

1 Answers1

2

Code Analysis can't tell that frm is still doing anything after it exits scope. In this specific case, the object needs to stay alive after the function is done with it.

The "correct" way to handle this is to maintain a reference to frm in the parent form. This reference can then be disposed in the Dispose() method of the parent form.

private FormCustomerList frm;
private void barButtonItem1_ItemClick(object sender, ItemClickEventArgs e)
{
    frm = new FormCustomerList();
    frm.MdiParent = this;
    frm.Show();
}

If you have multiple sub forms that can be created (which is likely if you're using MDI), you can maintain a List<> of child forms.

private List<FormCustomerList> frms = new List<FormCustomerList>();
private void barButtonItem1_ItemClick(object sender, ItemClickEventArgs e)
{
    FormCustomerList frm = new FormCustomerList();
    frms.Add(frm);
    frm.MdiParent = this;
    frm.Show();
}
BJ Myers
  • 6,617
  • 6
  • 34
  • 50