Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么VisualStudioIDE有时会初始化;这个.components对象:其他时候不是吗?_C#_Visual Studio_Winforms_Visual Studio 2008_Visual Studio 2005 - Fatal编程技术网

C# 为什么VisualStudioIDE有时会初始化;这个.components对象:其他时候不是吗?

C# 为什么VisualStudioIDE有时会初始化;这个.components对象:其他时候不是吗?,c#,visual-studio,winforms,visual-studio-2008,visual-studio-2005,C#,Visual Studio,Winforms,Visual Studio 2008,Visual Studio 2005,我最近注意到VisualStudio Designer(C#)的一些行为,我不明白,想知道是否有人可以澄清 其中我的一些Windows窗体,设计器生成的第一行代码读取 this.components = new System.ComponentModel.Container(); 在这种情况下,dispose方法在同一设计器文件中,dispose方法在case“if”条件下放置两个“dispose”调用,如下所示: protected override void Dispose(boo

我最近注意到VisualStudio Designer(C#)的一些行为,我不明白,想知道是否有人可以澄清

其中我的一些Windows窗体,设计器生成的第一行代码读取

this.components = new System.ComponentModel.Container();
在这种情况下,dispose方法在同一设计器文件中,dispose方法在case“if”条件下放置两个“dispose”调用,如下所示:

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
            base.Dispose(disposing);
        }
    }
i、 e.除非disposing为true,且components不为null,否则不会调用任何内容

在其他一些表单上,设计器生成的代码中的第一行丢失。在这些情况下,base.Dispose调用本身不在“if”条件下

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }
我在跟踪一个表单未关闭的bug时注意到了这一点,其中this.components为null,而base.Dispose调用在该条件下(我怀疑设计器代码被篡改,但这是另一回事)

是什么控制了这种行为


(该项目中的一些早期表单是在VS 2005中创建的,我们现在使用VS 2008-clue?

有趣的小故障!听起来确实像是某个版本的设计器/模板中的一个bug。当然,如果你认为设计器代码被篡改了,那么不管怎样,所有的赌注都很低

但是,在VS2008中,它生成的版本无疑是正确的:

if (disposing && (components != null))
{
    components.Dispose();
}
base.Dispose(disposing);
因此调用了base
Dispose(…)
。不幸的是,我还没有准备好VS2005来测试它。但是-它在必须初始化组件之前不会初始化组件-声明是:

private System.ComponentModel.IContainer components = null;
然后,如果需要,将其填充到
InitializeComponent

private void InitializeComponent()
{
    this.components = new System.ComponentModel.Container();
    //...
}

我猜使用这个构造,它只需要维护
InitializeComponent
(而不是字段本身)。

我看到过这种情况,而且我偶尔也会从Dispose方法中收到警告,关于组件从未赋值或未定义

我认为这是两件事的结合:


  • Visual Studio版本之间的代码生成略有不同
  • 仅当文件中没有Dispose方法时,才会生成Dispose方法,而每次都会生成InitializeComponent(以及相关的声明)

  • 这会导致InitializeComponent/declarations部分与Dispose方法不协调。

    这是可复制的行为。创建新表单时,它从包含This.components构造函数调用的框架开始。然后添加组件时(例如计时器)如果再次删除它,设计器将重新生成代码,现在没有构造函数调用。这不是bug

    Fwiw,骨架代码由
    Common7\IDE\ItemTemplates\CSharp\Windows Forms\1033\Form.zip\Form.designer.cs生成


    在if()语句中看到base.Dispose()调用是一个错误。这可能是自导的。也可能是一个测试版的框架代码。VS2005做得很好。请检查ItemsTemplatesCache文件夹。

    6年后,这个问题仍然发生。我已经设法找到了至少一个导致它发生的原因

    当测试组件是否具有采用IContainer的构造函数时,System.ComponentModel.Design.Serialization.ComponentCodeDomainSerializer会缓存对项目IContainer类型的引用。如果随后在同一解决方案中为另一个项目保存对象,或者可能在您的组件中进行了其他类型的更改项目中,ComponentCodeDomainSerializer无法再找到构造函数,因为IContainer的类型不再等于其缓存类型


    如果您的项目经常出现这种情况,则存在一个非常糟糕的解决方案。将此类或
    VisualStudioWorkaroundSerializer
    类添加到解决方案中。然后添加属性
    DesignerSerializer(GetType(VisualStudioWorkaroundSerializer)、GetType(CodeDomainSerializer))
    到你的组件。每当你的组件被保存时,这个自定义序列化程序就会检测到问题,修复它,并在这个问题即将发生时强迫你再次保存。

    我也不行,马克。我今晚必须在家里试试。谢谢。“如果你认为设计器代码被篡改了”-是我,因为我不知道如何调整它!谢谢nobugz。我现在也有机会在VS2005中尝试这个场景。这很好。我只能假设,正如你所说,这是“自我诱导的”。“现在没有构造函数调用”。那么,
    (组件!=null)的意义是什么呢
    检查任何地方是否没有
    组件
    初始化?谁,何时何地初始化
    组件
    ?顺便说一句,是从VS2010.NET4.0来的。您似乎有一个新问题。您可以通过单击“提问”按钮来提问。@HansPassant那么我们不应该担心它,因为GC释放了例如计时器吗?“Visual Studio的两个版本之间”-来自于在VS2010、.NET4.0中创建新的Windows窗体应用程序,而不使用任何其他版本(尽管UI在PC上安装了VS2008)