在Visual Studio调试模式下复制对象值

189
在Visual Studio调试模式下,可以将鼠标悬停在变量上以显示其值,然后右键单击“复制”,“复制表达式”或“复制值”。如果变量是对象而不仅仅是基本类型,则有一个+号可展开和探索对象。是否有一种方法可以将所有内容复制到剪贴板中?

使用快速查看和内置工具很容易解决这个问题:我的看法是 - Dominik Sand
17个回答

244
在即时窗口中,输入 ?name_of_variable,这将打印出 所有内容,你可以手动将其复制到任何地方,或者使用即时窗口的日志记录功能自动将其写入文件。 更新: 我假设你在问如何复制/粘贴值的嵌套结构,以便可以在文本中搜索它,或者保存在一边以后比较对象的状态。如果我没错的话,你可能想看看我创建的Visual Studio商业扩展程序,叫做 OzCode,它通过“搜索”和“比较”功能可以更轻松地进行这些操作。 更新2: 为了回答@ppumkin的问题,我们的 新EAP 有一个新的导出功能,允许用户将变量值导出为Json、XML、Excel或C#代码。 完整声明: 我是描述此处工具的共同创造者。

5
如果它能递归展开以显示所有内容,那就更好了。可能会有很多文本,但我可以搜索树中更深处的值。 - Kobus Smit
3
我非常喜欢BugAid的功能。我现在正在下载试用版,当它过期并且我开始感到很烦恼时,我会让我的老板为我购买它。 :) - Piotr Kula
24
有人知道如何输出超过100个项目吗?在立即窗口中显示了前100个项目后,会出现以下内容:< More...(显示了335个项目中的前100个。)> - lachs
13
“即时窗口”是什么意思? - alex
7
在 Visual Studio 中,转到“调试(Debug)” > “窗口 (Windows)” > “立即执行 (Immediate)” - 它允许您在调试过程中输入要评估或执行的表达式。 - JTech
显示剩余14条评论

79
你可以在立即窗口中运行以下代码,并将对象的序列化 XML 表示导出到一个 xml 文件中:
(new System.Xml.Serialization.XmlSerializer(obj.GetType())).Serialize(new System.IO.StreamWriter(@"c:\temp\text.xml"), obj)

来源:Visual Studio如何从调试器中序列化对象


6
应该给这个帖子点赞,这样人们就可以更容易地找到它。在发现这个很好的解决方案之前,我浏览了很多类似的SO问题,这个方案允许我在长时间运行的程序崩溃后将一个大型List<List<byte>>转储到XML文本文件中。只有一个补充:当我第一次运行它时,我遇到了一个错误:“评估需要临时运行线程。使用监视窗口执行评估。”刷新监视窗口后,再尝试运行命令,就成功了。 - Craig.Feied
Bat_Programmer: 你可能需要修改你回答的第一行,因为它暗示输出的是对象列表,而实际上输出的是单个指定对象(变量)的序列化XML表示。 - Craig.Feied
无法评估表达式,因为当前方法的代码已经被优化。 - Falco Alexander
5
如果你有 JSON 数据,可以这样做:File.WriteAllText(@"c:\movie.json", JsonConvert.SerializeObject(movie));。这行代码将把名为 "movie" 的对象序列化成 JSON 格式,并将结果写入到一个名为 "c:\movie.json" 的文件中。 - user890332
The debugger is unable to evaluate this expression. I am using Visual Studio 2019; I substituted obj with the variable name which is type System.Collections.Generic.List 1[[System.ValueTuple 3[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7]] - Drew

49

来自https://dev59.com/dGMk5IYBdhLWcg3w-Spm#23362097的最受欢迎的答案:

如果你非常幸运地已经在你的应用程序域中有Json.Net,那么将以下内容复制到你的立即窗口即可:

Newtonsoft.Json.JsonConvert.SerializeObject(someVariable)
编辑:使用.NET Core 3.0,下面的代码也可以运行:
System.Text.Json.JsonSerializer.Serialize(someVariable)

3
太棒了。谢谢兄弟! - amedina
1
JSON格式不正确,需要执行更多的操作才能格式化它,这很烦人。Visual Studio应该立即将格式化后的JSON复制到剪贴板中。调试过程可以更加顺畅。 - ADM-IT
3
你可以将其添加为观察表达式,并从那里复制未转义的JSON。 - Heinrich Ulbricht
标识符“System”未定义。 - KeyC0de
@KeyC0de,你需要在Debug > Window下打开Immediate控制台(Ctrl + Alt + I - undefined

32

1
似乎在处理更大的对象列表时出现问题。 - Bat_Programmer
我喜欢Object Exporter,但它不支持Visual Studio 2019的新版本:VSIXInstaller.NoApplicableSKUsException: This extension is not installable on any currently installed products. - Jess
1
当时这是一个不错的选择。可惜它不能与新版本一起使用。 - Animesh

29

您可以为该对象添加一个监视器,在监视窗口中展开并选择您想要复制的所有内容,然后将其复制。


1
谢谢PMN也帮了我。通过手动展开树(如果有右键单击,展开所有会很好),然后将其复制到剪贴板中,我可以粘贴它并搜索我在树的深处正在寻找的值。 - Kobus Smit

4

通过使用属性装饰你的类和方法,你可以在调试时使用DebuggerDisplay属性来显示对象中的特定值,例如:

[DebuggerDisplay("Person - {Name} is {Age} years old")]
public class Person
{
  public string Name { get; set; }
  public int Age { get; set; }
}

问题是,我需要能够复制所有对象内容,而不仅仅是其中的一些。是的,我可以使用足够复杂的DebbuggerDisplay属性来构建整个对象,但是对类的任何更改也需要在属性中进行更改。 - Farinha
@Farinha 你想对这个对象做什么?也许可以有一个属性,它是它的序列化 XML 版本。 - Dave Anderson

3

我经常使用:

string myJsonString = JsonConvert.SerializeObject(<some object>);

我复制了字符串的值,但不幸的是也复制了反斜杠。

要删除反斜杠,请访问此处: https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_replace

然后在 <p id="demo">Visit Microsoft!</p> 元素内替换文本为你复制的文本。 然后将 var res = str.replace("Microsoft", "W3Schools"); 行替换为

var res = str.replace(/\\/g, '')

请运行这些新更改,但不要忘记点击右侧的“尝试”按钮。 现在,您应该拥有对象的所有文本以JSON格式,您可以将其放入JSON格式化程序中,例如http://jsonformatter.org,或者您现在可以使用http://json2csharp.com/来创建POCO。

3

ObjectDumper.NET

这是一个很棒的方法!

  1. 你可能需要这些数据进行单元测试,所以可以创建一个临时测试文件Sandbox.cs或者创建控制台应用程序。
  2. 确保获取NuGet包ObjectDumper.NET,而不是ObjectDumper。
  3. 运行此测试(或控制台应用程序)。
  4. 查看测试输出或文本文件,以获取C#初始化器代码!

代码:

[TestClass]
public class Sandbox
{
    [TestMethod]
    public void GetInitializerCode()
    {
        var db = TestServices.GetDbContext();
        var list = db.MyObjects.ToList();
        var literal = ObjectDumper.Dump(list, new DumpOptions
        {
            DumpStyle = DumpStyle.CSharp,
            IndentSize = 4
        });
        Console.WriteLine(literal); // Some test runners will truncate this, so use the file in that case.
        File.WriteAllText(@"C:\temp\dump.txt", literal);
    }
}

我曾经使用Object Exporter,但它已经过去5年,并且在Visual Studio中不再受支持。看起来Visual Studio扩展程序时有时无,但希望这个NuGet包会一直存在!(截至本文撰写时也在积极维护)


3

Object Dumper 是一个免费且开源的扩展,可供 Visual StudioVisual Studio Code 使用。

Dump as” 命令可以通过 CodeImmediate 窗口中的上下文菜单获得。

它能将对象导出为以下格式之一:

  • C# 对象初始化代码,
  • JSON,
  • Visual Basic 对象初始化代码,
  • XML,
  • YAML。

我认为搭配Diff 工具 可以更加方便实用。

我是这个工具的作者。


1
我知道我来晚了,但我编写了一个JSON实现,可以将对象序列化为JSON输出。使用Newtonsoft.Json引用。
private static void WriteDebugJSON (dynamic obj, string filePath)
{
    using (StreamWriter d = new StreamWriter(filePath))
    {
        d.Write(JsonConvert.SerializeObject(obj));
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接