在 Linqpad 和 Visual Studio 之间架起桥梁 (结合 JSON 和扩展方法)
这将允许您轻松地将 Linqpad 代码集成到 Visual Studio 中
下载文件包含两个项目和 Linqpad 示例代码。
引言
如果您还没有听说过 Linqpad,您应该 下载 它并试用一下。它是一个类似记事本的应用程序,可以让您快速编写 C# (VB, SQL, E# & F#) 代码,并即时编译运行。它在处理 Linq 方面非常有用,但我经常将其用作临时代码编辑器,每当需要快速测试一个假设或一些代码时。
别误会我的意思。我爱 VS,当我需要调试一些复杂的代码时,我第一个就会启动它,设置断点,并利用它提供的所有功能。但是,当我想要模拟一个对象或测试一个 Linq 表达式时,我通常不会启动 VS (半个 G 的内存占用,更长的加载时间,需要创建一个新项目,构建,编译,您懂的),而是会在 Linqpad 中完成。
Linqpad 我最喜欢的功能之一是 .Dump()
方法。它可以让您快速地将您正在处理的任何内容转储到屏幕上。字符串、对象、列表,应有尽有。作为额外的奖励,它还会返回对象,因此您也可以将其作为临时输出的延续,例如
var list = Enumerable.Range(1,6)
.Dump("list of six ints")
.Where(x=> x%2 ==0)
.Dump("only the pair ones")
.Select (x => x*3)
.Dump("selecting the pair ones times three");
将产生类似如下的结果
现在,有时我会遇到需要调用“大杀器”的时候。这通常涉及将我的 Linqpad 代码复制到现有解决方案,或创建一个新解决方案。这也不是什么大麻烦,但我需要手动删除所有 .Dump()
调用,或者将它们注释掉。
让我们看一个例子
这时,就轮到 巨龙 精灵 (Linqpad) 出场了
在本教程中,我将使用以下 Genie
类
class Genie{
public Genie( int aYears = 1000
, int aWishCount = 3
, string aColor = "Blue" )
{
YearsInTheBottle = aYears ;
WishesToGrant = aWishCount ;
Color = aColor ;
}
public int YearsInTheBottle { get; set; }
public int WishesToGrant { get; set; }
public string Color { get; set; }
public void GrantWish(string aWish) {
if ( WishesToGrant>0 )
{
Console.Out.WriteLine( "Your wish is my command." );
Console.Out.WriteLine( "[{0}] granted.{1}"
, aWish
, Environment.NewLine );
WishesToGrant--;
if (WishesToGrant==0)
Console.Out.WriteLine( "I'm finally freeeeeee...{0}"
, Environment.NewLine);
}
else
Console.Out.WriteLine("You're all out of wishes ...");
}
}
如果您看过 《阿拉丁》,您应该知道我在说什么。如果没看过,那太遗憾了。快去看吧。
现在您可以将这段代码粘贴到 Linqpad 中 (在语言选项中选择 "C# program"),然后执行以下操作
void Main()
{
var genie = new Genie().Dump();
genie.GrantWish("I want to be smart");
genie.GrantWish("I want to be a lumberjack");
genie.Dump();
genie.GrantWish("I want to be the king of Narnia");
genie.GrantWish("I want to get more wishes");
genie.Dump();
}
结果将如下所示
好了,完成了!我已经测试了我的类,有了可视化输出,就可以继续我的下一个项目了。
传统的 Visual Studio 解决方案
常规步骤大致如下
- 创建一个新的控制台解决方案
- 将 Linqpad
main
方法中的代码粘贴到您的控制台main
方法中 - 意识到您没有
.Dump()
- 将
Genie
类粘贴到您的解决方案中 - 重写
ToString()
以便获得一些输出public override string ToString() { return string.Format( "YearsInBottle:{1}{0}WishesToGrant{2}{0}Color:{3}{0}" , Environment.NewLine , YearsInTheBottle , WishesToGrant , Color ); }
- 将所有
genie.Dump()
更改为Console.Out.WriteLine(genie);
恭喜!现在您可以运行您的项目,您将看到类似以下内容
《帝国》精灵反击战
一种解决方法是创建一个扩展方法来打印您的 Genie
对象。这种方法的缺点是它不是通用的,您需要为每个想要调试的类执行此操作。
您可以尝试从头开始编写 Dump()
(或者也许请求作者提供代码),但这两种方法对我来说都太激进了。
您还可以使用反射来获取对象的所有属性及其值,处理一些特殊情况并自己格式化。缺点是通常的“反射很慢”,而且代码也不是最漂亮的 (是的,Newtonsoft 可能会这样做,但它已经写好、经过测试并针对性能进行了优化)。
这是另一个解决方案
1. 安装 NewtonSoft JSON
进入您的 Nuget 包管理器,安装 NewtonSoft JSON (您不必局限于版本 6,我相信现在已经发布了版本 10)。
2. 在您的控制台项目中创建一个名为 ExtensionMethods.cs 的新文件。
在这个文件中,我们将为 Dump()
方法添加我们的扩展方法。如果您觉得这有点过了,答案是否定的。它是模块化的,我通常会为特定项目需要其他扩展方法,所以它们都会在这个文件中愉快地共存。
您的文件应该如下所示
using System;
using Newtonsoft.Json;
namespace JSON_Dump
{
public static class ExtensionMethods
{
/// <summary>
/// This is a simple (and lazy, read: effective) solution. Simply send your
/// object to Newtonsoft serialize method, with the indented formatting, and
/// you have your own Dump() extension method.
/// </summary>
/// <typeparam name="T">The object Type</typeparam>
/// <param name="anObject">The object to dump</param>
/// <param name="aTitle">Optional, will print this before the dump.</param>
/// <returns>The object as you passed it</returns>
public static T Dump<T>(this T anObject, string aTitle = "")
{
var pretty_json = JsonConvert.SerializeObject( anObject, Formatting.Indented );
if ( aTitle != "" )
Console.Out.WriteLine( aTitle + ": " );
Console.Out.WriteLine( pretty_json );
return anObject;
}
}
}
(我一直忘记从 VS 粘贴内容会保留格式…太棒了…)
所有这些都是接收一个对象 (我们不关心它的类型),将其交给 Newtonsoft.Json
,然后问:“您能帮我把这个对象变得好看一点吗?”。Newtonsoft Json 会将您的对象转换为 JSON,然后为您缩进,完全免费。我们会将其输出到屏幕,并返回我们收到的对象,因此您仍然可以在上面的 示例 中使用它。
3. 继续使用您的 Linqpad 代码 (包括 .Dump()
)
现在您可以直接将 Linqpad 代码粘贴到您的 main 方法中,它就会正常工作。无需任何更改。 :)
粘贴并运行代码后的效果如下
如您所见,您会得到漂亮的 JSON 对象表示,它是缩进的,如果您有嵌套对象,它们会进一步缩进。
好消息
这很容易,而且不需要您付出太多努力。您可以直接将扩展文件粘贴到您的项目中,或者如果您愿意,您可以将所有常用的扩展方法编译成一个 DLL,然后直接引用它 (我就是这么做的,因为我有一些其他常用的绝妙扩展方法)。
坏消息
如果您还没有学到,生活中没有什么是免费的。您不必担心重写 ToString()
的好处,但您需要付出磁盘空间。Newtonsoft DLL (将被复制到您的输出文件夹) 大约 433kb,与之配套的 XML 还有 435kb。这不算什么大事,尤其是如果您已经在项目中使用 Newtonsoft JSON 进行其他操作,但如果您想发布一个小型可执行文件,您可能需要坚持重写 ToString()
。 :)
总结
希望您觉得这很有用,即使没有,我也希望它能给您一些有趣的思考。
如果您想了解更多关于 Newtonsoft JSON 的信息,请访问 项目主页。
如果您想了解更多关于扩展方法的信息,请访问此 MSDN 页面。
如果您觉得这篇文章有帮助,请给文章投票,留下评论,并随时在此文章中回帖。
历史
- 2014 年 6 月 24 日:首次发布
- 2014 年 6 月 29 日:修复了锚点标签代码和一些格式问题
- 2015 年 5 月 8 日:又一轮格式和阅读增强
- 2017 年 9 月 29 日:修复了一个拼写错误并添加了另一个选项。