我在我的VS2012项目上运行了代码分析选项,它发现了以下内容;
拥有一次性字段的CA1001类型应该是在“DataGridViewColumnSelector”上一次性实现IDisposable,因为它创建了以下IDisposable类型的成员:“CheckedListBox”、“ToolStripDropDown”。如果'DataGridViewColumnSelector‘以前已经发布过,那么向这种类型中添加实现IDisposable的新成员被认为是对现有消费者的重大改变。DataGridColSelector DataGridViewColumnSelector.cs
我创建了我的类,DataGridViewColumnSelector继承了IDisposable,我想知道在dispose方法中放入什么内容。
最新情况:
这是我的尝试。自从我让这个类被密封后,代码分析已经停止了。我还是不确定我是不是“做得对”
public sealed class DataGridViewColumnSelector :IDisposable
{
private DataGridView mDataGridView = null;
private CheckedListBox mCheckedListBox;
private ToolStripDropDown mPopup;
public delegate void CustomRightClickDelegate(object sender, MouseEventArgs e);
public event CustomRightClickDelegate GridRightClickEvent;
/// <summary>
/// The max height of the popup
/// </summary>
public int MaxHeight = 300;
/// <summary>
/// The width of the popup
/// </summary>
public int Width = 200;
public DataGridView DataGridView
{
get { return this.mDataGridView; }
set
{
if (this.mDataGridView != null) this.mDataGridView.MouseDown -= this.mDataGridView_MouseDown;
this.mDataGridView = value;
if (this.mDataGridView != null) this.mDataGridView.MouseDown += this.mDataGridView_MouseDown;
}
}
void mDataGridView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
if( this.mDataGridView.HitTest(e.X, e.Y).Type == DataGridViewHitTestType.ColumnHeader)
{
this.mCheckedListBox.Items.Clear();
foreach (DataGridViewColumn c in this.mDataGridView.Columns)
{
this.mCheckedListBox.Items.Add(c.HeaderText, c.Visible);
}
int PreferredHeight = (this.mCheckedListBox.Items.Count*20);
this.mCheckedListBox.Height = (PreferredHeight < this.MaxHeight) ? PreferredHeight : this.MaxHeight;
this.mCheckedListBox.Width = this.Width;
this.mPopup.Show(this.mDataGridView.PointToScreen(new Point(e.X, e.Y)));
}
else
{
if (this.GridRightClickEvent != null)
{
this.GridRightClickEvent.Invoke(sender, e);
}
}
}
}
public DataGridViewColumnSelector()
{
this.mCheckedListBox = new CheckedListBox();
this.mCheckedListBox.CheckOnClick = true;
this.mCheckedListBox.ItemCheck += new ItemCheckEventHandler(this.mCheckedListBox_ItemCheck);
ToolStripControlHost mControlHost = new ToolStripControlHost(this.mCheckedListBox);
mControlHost.Padding = Padding.Empty;
mControlHost.Margin = Padding.Empty;
mControlHost.AutoSize = false;
this.mPopup = new ToolStripDropDown();
this.mPopup.Padding = Padding.Empty;
this.mPopup.Items.Add(mControlHost);
}
public DataGridViewColumnSelector(DataGridView dgv)
: this()
{
this.DataGridView = dgv;
}
void mCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
{
this.mDataGridView.Columns[e.Index].Visible = (e.NewValue == CheckState.Checked);
}
public void Dispose()
{
//http://stackoverflow.com/questions/6826958/c-toolstripdropdown-doesnt-dispose-destroyhandle
// http://msdn.microsoft.com/en-au/library/b1yfkh5e%28v=vs.71%29.aspx
// Kirsten says I dont feel sure about what I am doing here.
mCheckedListBox.Dispose( );
mPopup.Dispose( );
GC.SuppressFinalize(this);
}
}发布于 2013-04-22 08:08:59
你应该叫处分,然后你的表单处理。
还有。IDisposable的实现缺少一些重要的东西。
1)您应该确保没有订阅自定义事件的事件。这最终可能会导致应用程序内存泄漏。
//in dispose
GridRightClickEvent = null2) MSDN有一个实现IDisposable的最佳实践
public sealed class DataGridViewColumnSelector : IDisposable
{
//removed: ~DataGridViewColumnSelector (){ Dispose(false); /*destructor*/ }
//class context omitted
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if(disposing)
{
//kill the reference - do not dispose the object.
//it was *not* created here, os it should *not* be disposed here
mDataGridView = null;
//makes sure no outside object has a reference
//to the event - thus keeping it alive when it should be garbagecollected
GridRightClickEvent = null;
if(mCheckedListBox != null) mCheckedListBox.Dispose();
if(mPopup != null) mPopup.Dispose();
if(mControlHost != null) mControlHost .Dispose();
}
}
}https://stackoverflow.com/questions/16139585
复制相似问题