Visual Basic.NET 7.x (2002/03)VBScriptVisual Studio .NET 2003.NET 1.1中级开发Visual StudioWindows.NETVisual BasicC#
Visual Studio 2003 的 C# 代码运行宏





3.00/5 (4投票s)
使用此宏,您可以检查代码片段的输出,而无需创建新的项目/窗体。您可以直接在当前代码窗口中执行此操作。
引言
很多时候,程序员想要执行一小段代码来查看一些简单计算的输出。他们不得不浪费时间创建一个新项目,编写示例代码并在某个窗体上执行它。
例如,我们想在以下情况下检查输出
- 
int i = 2, j; j = i * 3; return j; 
- 
DateTime dt = new DateTime(); return dt; 
问题
获得输出的一个简单解决方案是编写一个宏,它可以编译代码片段并为您提供解决方案,全部在您现在使用的同一代码窗口中。
因此,这是我能想到的宏的要求列表
- 它应该显示作为计算结果或简单代码执行结果的变量的值。
- 程序员不必创建新的项目/窗体。程序员只需选择他/她想要执行的代码片段。
- 必须有一些包含 namespace的工具。
 
 
Using the Code
为了解决代码片段的执行问题,我使用了反射。我还假设一些自定义关键字来识别返回变量。
以下是宏中涉及的步骤
- 首先,在编译代码之前,我们需要将代码片段转换为一个完整的类。
- 然后我们编译代码片段。直接从这里报告任何错误。
- 然后我们创建一个新编译的类的对象。
- 执行包含代码片段的虚拟函数。
- 将结果输出到输出窗口。在这里,我假设当我们想要在编译中包含任何 namespace时,我们使用关键字using。关键字return用于识别返回变量。
在这里,我们有一个代码片段,它拾取用户选择的源代码来执行。
'Check if any special using is used in code
        For i As Integer = iStart To iEnd
            ActiveDocument().Selection.GotoLine(i)
            ActiveDocument().Selection.SelectLine()
            'Check if the user wants to include some special namespace
            If (ActiveDocument().Selection.Text.Trim().IndexOf("using") >= 0) Then
                'add the assembly to the future code
                strUsing += ActiveDocument().Selection.Text.Trim()
            ElseIf (ActiveDocument().Selection.Text.Trim().IndexOf("return") >= 0) Then
                'Set the return string for the function
                strReturn = ActiveDocument().Selection.Text.Trim().Replace(";", "") + _
                                                               ".ToString();"
            ElseIf (ActiveDocument().Selection.Text.Trim().IndexOf("refer") >= 0) Then
                compilerOptions.ReferencedAssemblies.Add(ActiveDocument(). _ 
            Selection.Text.Trim().Replace(";", "").Replace("refer", "").Trim())
            Else
                'else add it as source
                strSource += ActiveDocument().Selection.Text.Trim()
            End If
        Next
如上面的代码片段所示,我们获取用户选择并循环遍历所有行。如果我们找到两个关键字, using 和 return,我们进行适当的设置。所有其他行都被认为是直接执行的语句。
在此步骤之后,我们编译虚拟代码并创建一个新编译的类的对象
'Get the Assembly from the compiled code
        newAssembly = compilerResults.CompiledAssembly()
        'Get the method and call it
        Dim objTypes() As Type = newAssembly.GetTypes()
        Dim t As Type = newAssembly.GetType("TestNamespace.TestClass")
        Dim obj As Object = Activator.CreateInstance(t)
        Dim method As MethodInfo = t.GetMethod("TestMe")
        'Call the output of the method
        owpane.OutputString("Output = " + method.Invoke(obj, Nothing))    
我们只需运行该函数并使用 ToString() 方法来获取变量的文本。
我们还使用一个简单的函数来获取 Visual Studio 中 Output 窗口的句柄,我们在其中向用户显示输出。
    Function GetOutputWindowPane(ByVal Name As String, _
        Optional ByVal show As Boolean = True) As OutputWindowPane
        Dim win As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
        If show Then win.Visible = True
        Dim ow As OutputWindow = win.Object
        Dim owpane As OutputWindowPane
        Try
            owpane = ow.OutputWindowPanes.Item(Name)
        Catch e As System.Exception
            owpane = ow.OutputWindowPanes.Add(Name)
        End Try
        owpane.Activate()
        Return owpane
    End Function
缺点
- 这个宏的一些主要缺点是它没有太多的错误处理。
 它只适用于 C#,但可以很容易地修改为也适用于 VB.NET。
- 无法计算复杂的对象。例如 Datatable,Dataset。
更新历史
- 2007 年 9 月 27 日:发表文章(包含大量错误的程序代码:)
- 2007 年 9 月 28 日:更改了 Zip 中捆绑的文件(添加了 Imports 和常用函数)


