gpt4 book ai didi

c# - 我们什么时候应该为组件实现带有 IContainer 参数的构造函数?

转载 作者:行者123 更新时间:2023-12-04 08:07:28 26 4
gpt4 key购买 nike

假设我有一个 WinForms 组件。
它可以是一个基于 System.ComponentModel.Component 的类或 System.Windows.Forms.Control类(实际上 Control 继承了 Component )。
我的组件可能会使用我们应该正确处理的其他 .NET 类 - Pens、Brushes、ContextMenuStrips 等。我在 Dispose(bool disposing) 的实现中按预期处理它们方法根据众所周知的IDisposable图案。
我想知道什么时候我必须添加一个接受 IConatiner 的特殊构造函数参数,因此表单设计器将注册我的组件实例,以便在表单关闭期间自动处理资源:

private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
...
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
}

protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
我分析了 Dispose(bool disposing)的源代码一些WinForms Component的方法试图找到答案,但情况仍然不清楚。
例如, ContextMenuStrip组件有这样的构造函数,但是 DataGridView没有 - 尽管两者都有足够的对象,但它们在它们的 Dispose(bool disposing) 中处理实现。
任何提示或想法?

最佳答案

如果您是组件作者,作为最佳实践,我的建议是实现接受 IContainer 的构造函数重载。 ,因为当一个组件有这样的构造函数时,当开发者在设计图面上放置一个组件的实例时,设计者会生成一段代码来关心组件的处理。

  • 您的组件在 ToolBox 中可用吗?
    对于可以通过工具箱访问的组件,如果用户将组件放在设计器上,那么他们不应该关心组件的处理。所有的标准组件都遵循这种模式,用户从不关心他们通过设计器创建的控件和组件的处置,因此关心设计时支持是组件作者的责任。
  • 你有什么要处理的组件吗?
    如果你没有什么要处理的,那么这个重载不是那么重要,但是如果你有什么要处理的,那么你应该关心处理。正如在前面的要点中提到的,由于用户可能会将您的组件放在设计器上并指望设计器处理它们,那么您有责任提供该方法,以便设计器生成处理代码。否则,将不会处理该组件,从而导致内存/句柄泄漏。

  • 作为组件用户
    作为组件用户,如果您在代码中创建组件(而不是在设计时删除它),您有责任在不再需要组件时处理它。您可能会发现这篇文章很有用: Why should I insert a non-UI Windows.Forms component from the designer?
    如果您从工具箱中删除一个组件,那么您无需担心它的处理。所有标准组件都会生成一个代码 o 在处理表单时处理组件。
    设计者生成的代码如何处理组件的处置?
    对于具有接受 IContainer 的构造函数的组件,当您将它们放在设计图面上时,设计器会生成一个代码来创建 components集合并将组件添加到该集合,然后在表单处理时处理该集合(包括其所有组件)。
    查看以下设计器生成的代码:
    private System.ComponentModel.IContainer components = null;

    protected override void Dispose(bool disposing)
    {
    if (disposing && (components != null))
    {
    components.Dispose();
    }
    base.Dispose(disposing);
    }

    InitializeComponent()
    {
    this.components = new System.ComponentModel.Container();
    ...
    ...
    this.myComponent = new MyComponent(this.components);
    ...
    ...
    }
    Dispose method of Container类(class):
    protected virtual void Dispose(bool disposing) {
    if (disposing) {
    lock (syncObj) {
    while (siteCount > 0) {
    ISite site = sites[--siteCount];
    site.Component.Site = null;
    site.Component.Dispose();
    }
    sites = null;
    components = null;
    }
    }
    }
    你会看到当你的表单被释放时,它会释放它在容器中找到的所有组件。

    关于c# - 我们什么时候应该为组件实现带有 IContainer 参数的构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66153587/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com