【问题标题】:VS2010 save array/collection data to a file while debuggingVS2010调试时将数组/集合数据保存到文件
【发布时间】:2011-08-25 17:34:00
【问题描述】:

在 VS2010 中调试时,有没有办法将数组/列表/集合数据保存到文件中?

例如,在这段代码中:

var addressGraphs = from a in context.Addresses
                    where a.CountryRegion == "Canada"
                    select new { a, a.Contact };

foreach(var ag in addressGraphs) {
   Console.WriteLine("LastName: {0}, Addresses: {1}", ag.Contact.LastName.Trim(),
                     ag.Contact.Addresses.Count());



   foreach(var Address in ag.Contact.Addresses) {
      Console.WriteLine("...{0} {1}", Address.Street1, Address.City);
   }
}

我想在“foreach”的第一行设置一个断点,然后将“addressGraph”中的数据保存到一个文件中。

其中“a”包含以下字段:

   int addressID
   string Street1
   string City
   <Ect.>

并且“联系人”包含以下字段:

   string FirstName
   string LastName
   int contactID
   <Ect.>

我希望文件包含集合中每个项目的每个字段的值。

我没有看到明显的方法来做到这一点。有可能吗?

【问题讨论】:

  • 澄清一下,我需要能够在任意集合上即时执行此操作。必须向应用程序添加代码不符合我的需求。

标签: visual-studio-2010 debugging


【解决方案1】:

当你的断点被命中时,打开Immediate 窗口并使用Tools.LogCommandWindowOutput 将输出转储到一个文件中:

>Tools.LogCommandWindowOutput c:\temp\temp.log
?addressGraphs
>Tools.LogCommandWindowOutput /off

注意:您可以使用Log,它是Tools.LogCommandWindowOutput的别名


更新: &gt; 字符很重要。此外,log 别名区分大小写。 见截图:

【讨论】:

  • 我无法让“日志”在即时窗口中工作,但它确实可以在命令窗口中工作。
  • @casterle:您输入了&gt; 字符吗?这很重要。该字符告诉即时窗口您正在输入命令。
  • 我无法让“日志”在即时窗口中工作,但它可以在命令窗口中工作。在任一窗口中?命令显示:code {System.Data.Objects.ObjectQuery} 基础 {System.Data.Objects.ObjectQuery}:{System.Data.Objects.ObjectQuery} _name:“它”名称:“它”code 但不显示集合的内容。我错过了什么?
  • 我没有 - 我认为 '>' 是命令提示符。正如您所建议的,输入“>”修复了日志问题。我还需要做更多的事情来制作'吗?命令工作?
  • ? 不做深度序列化。最简单的方法是说?code.[Collection] 来显示集合的内容。 (注意我使用了假名,但你明白了)
【解决方案2】:

我也遇到过这样的问题,但是在VS2013中。我必须在调试时保存数组的内容。

例如,我需要保存一个名为“trimmedInput”的双精度数组的内容。我这样做:

  1. 从“调试”菜单(Ctrl+D、Q)打开 QuickWatch 窗口。

  2. 将变量放入表达式并按下重新计算按钮

  3. 您将看到所有值。现在你可以全选 (Ctrl+A) 并复制 (Ctrl+C)。

  4. 将它们粘贴 (Ctrl+V) 到您喜欢的编辑器中。以记事本为例。并使用它们。

这是我所知道的最简单的方法。无需额外的努力。希望我的描述对你有所帮助!

附:很抱歉屏幕截图上的非英文界面。所有必要的信息都写在正文中。

【讨论】:

    【解决方案3】:

    使用这种方法可以实现类似的效果:

    我构建了一个我在所有项目中使用的扩展方法,它是一种通用且更强大的 ToString() 方法,可以显示任何对象的内容。 我在这个链接中包含了源代码: https://rapidshare.com/files/1791655092/FormatExtensions.cs

    更新: 您只需将 FormatExtensions.cs 放入您的项目中并更改 FormatExtensions 的命名空间以与您的项目的基本命名空间一致。因此,当您处于断点时,您可以在监视窗口中输入: myCustomCollection.ToStringExtended()

    然后将输出复制到任何你想要的地方

    【讨论】:

    • 这听起来很有趣,虽然它确实需要代码,但它以一种轻松的方式完成,它对我有用。但是,我对整个 VS/C#/.NET 很陌生,不明白如何在我的项目中进行这项工作。您能否更具体地说明我如何使用您的代码?
    • 这是最快的方法:假设您有一个名为“MyClassLibrary”的类库项目,您将这段代码放在类库中,并将 FormatExtensions 的命名空间更改为“MyClassLibrary”。现在,您将在项目中的每个对象中都有扩展“ToStringExtended”。
    • 谢谢,这很容易。但是,它运行良好(不是总是有一个“但是”吗?)结果是一个长度为 139,395(!)个字符的字符串,这不是很有用,至少 WRT 是我想要完成的。我不认为有办法将输出格式化为类似于数据的结构?
    • 通过编码一切皆有可能:)。对我来说,这种格式很好,因为我主要用它在日志文件中写入复杂的变量。我只是认为您建议的这可能是另一种用途。如果您编写的版本格式更紧凑,请告诉我们。
    • 我一定会这样做的。再次感谢。
    【解决方案4】:

    您也可以在即时窗口中调用方法,因此我认为您最好使用 ObjectDumper 对象,例如 the one in the LINQ samplesthis one,然后在即时窗口中编写如下内容:

    File.WriteAllText("myFileName.txt", ObjectDumper.Dump(addressGraph));

    根据您决定使用的 ObjectDumper,您可以对其进行自定义以满足您的需求,并能够告诉它在倾倒对象时您希望它挖掘对象的深度。

    更新:您已在评论中澄清您要将数据保存到文件的原因是您可以搜索它,并在不同时间点对集合进行比较程序的执行或不同的运行。实际上,我为 Visual Studio 编写了一个商业扩展(称为BugAid),正是这样做的。有了它,您可以take snapshots of variables(通过右键单击它们并选择“保存变量”)然后在变量和您之前保存的其值的快照之间进行比较。就像在 diff 工具中一样,集合中每个项目的先前值和当前值并排显示,您可以在比较数据时通过search

    注意 1:快照目前无法保存到文件,只能在同一调试会话中进行比较。

    注意 2:在当前版本的 BugAid 中,搜索和保存快照都只适用于对象图的 3 级。在下一个版本中,您将能够控制搜索/保存数据的深度。

    如果这对您有帮助,请告诉我。

    【讨论】:

    • 这两种解决方案都要求我在转储集合之前更改我的代码。
    • 好吧,您可以通过从即时窗口调用 Assembly.Load("ObjectDumper.dll") 手动加载它。顺便说一句,你为什么要把它保存到文件中?
    • 我有兴趣在调试期间的某个时间点查看集合的内容。有几个原因我希望能够转储到文件(尤其是对于大量数据):1)所以我可以在数据中仔细阅读和搜索,2)所以我可以在运行之间区分数据或在代码中的不同点。
    • Re ObjectDumper:它没有做我正在寻找的事情,转储了数千行神秘信息,但据我所知,没有我正在寻找的集合字段值.
    • Re ObjectDumper,这很奇怪,也许是因为 addressGraphs 是匿名类型的集合,所以您看到的“神秘字符串”是编译器为匿名类型和自动属性生成的名称?无论如何,我用另一个选项更新了我的答案。
    【解决方案5】:

    Visual studio Gallery 上搜索:Object Exporter 扩展。
    请注意:据我使用,它有一个错误会阻止您偶尔导出对象。

    【讨论】:

      【解决方案6】:

      这是一个处理集合的解决方案。它是一个 VS 可视化工具,可在调试时在网格中显示集合值,并保存到剪贴板和 csv、xml 和文本文件。我在 VS2010 Ultimate 中使用它。虽然我没有对它进行过广泛的测试,但我已经在 List 和 Dictionary 上进行了尝试。

      http://tinyurl.com/87sf6l7

      它处理以下集合:

      •System.Collections classes  
         ◦System.Collections.ArrayList  
         ◦System.Collections.BitArray  
         ◦System.Collections.HashTable  
         ◦System.Collections.Queue  
         ◦System.Collections.SortedList  
         ◦System.Collections.Stack  
         ◦All classes derived from System.Collections.CollectionBase  
      
      •System.Collections.Specialized classes  
         ◦System.Collections.Specialized.HybridDictionary  
         ◦System.Collections.Specialized.ListDictionary  
         ◦System.Collections.Specialized.NameValueCollection  
         ◦System.Collections.Specialized.OrderedDictionary  
         ◦System.Collections.Specialized.StringCollection  
         ◦System.Collections.Specialized.StringDictionary  
         ◦All classes derived from System.Collections.Specialized.NameObjectCollectionBase  
      
      •System.Collections.Generic classes  
         ◦System.Collections.Generic.Dictionary
         ◦System.Collections.Generic.List  
         ◦System.Collections.Generic.LinkedList  
         ◦System.Collections.Generic.Queue  
         ◦System.Collections.Generic.SortedDictionary  
         ◦System.Collections.Generic.SortedList  
         ◦System.Collections.Generic.Stack  
      
      •IIS classes, as used by  
         ◦System.Web.HttpRequest.Cookies  
         ◦System.Web.HttpRequest.Files  
         ◦System.Web.HttpRequest.Form  
         ◦System.Web.HttpRequest.Headers  
         ◦System.Web.HttpRequest.Params  
         ◦System.Web.HttpRequest.QueryString  
         ◦System.Web.HttpRequest.ServerVariables  
         ◦System.Web.HttpResponse.Cookies  
      

      还有几个兼容 VB6 的集合

      【讨论】:

        【解决方案7】:

        在“立即窗口”中打印以下内容以获取二进制转储:

        byte[] myArray = { 02,01,81,00,05,F6,05,02,01,01,00,BA };
        
        myArray
          .Select(b => string.Format("{0:X2}", b))
          .Aggregate((s1, s2) => s1 + s2)
        

        这将打印如下内容:

        0201810005F60502010100BA
        

        更改 '.Aggregate(...)' 调用以在字节之间添加空格,或者您喜欢的任何内容。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-03
          相关资源
          最近更新 更多