C#, Scripting の勉強用コード退避

自分用退避用。.NET Framework 4.7.2 / WPF プロジェクトで、NuGet で「Microsoft.CodeAnalysis.CSharp.Scripting」とかをインストールしたやつ。

MainWindow.xaml

<Window x:Class="WpfApp8.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp8"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Margin="10" Content="button1" Click="Button_Click" />
    </Grid>
</Window>

MainWindow.xaml.cs

//using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
using System.Threading.Tasks;
using System.Windows;
//using System.Windows.Controls;
//using System.Windows.Data;
//using System.Windows.Documents;
//using System.Windows.Input;
//using System.Windows.Media;
//using System.Windows.Media.Imaging;
//using System.Windows.Navigation;
//using System.Windows.Shapes;

namespace WpfApp8
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            // 参照 dll の追加と、 using (名前空間の省略)の設定
            var options = ScriptOptions.Default
                .AddReferences(new string[]
                {
                    "System",
                    "System.Core",
                    "System.Data",
                    "System.Data.DataSetExtensions",
                    "System.Xml",
                    "System.Xml.Linq"
                })
                .AddImports(new string[]
                {
                    "System",
                    "System.Collections.Generic",
                    "System.IO",
                    "System.Linq",
                    "System.Text",
                    "System.Threading.Tasks"
                });

            // 実行させたいソースコード。実際には TextBox 等の入力系コントロールからか、ファイル読み込みから取得して扱う
            var code = @"

void Test2(string value)
{
    Console.WriteLine($@""called Test2(""""{value}"""") in inside."");
}

Test2(""hello!"");



class Class1
{
    public string Name { get; set; }

    public Class1(string name)
    {
        Name = name;
    }
}

var obj = new Class1(""hello!2"");
Test2(obj.Name);



// Test1() メソッドは、このソースコード内では定義していないが、外からインジェクションしている?ので呼び出せる
var x = Path.Combine(""C:Sample"", ""test.cs"");
Test1(x);


";

            try
            {
                // 実行。this (MainWindow) ではなく、会話専用のクラスを定義しておいて、インスタンス生成して渡す方がいいかも
                //await CSharpScript.RunAsync(code: code, options:options, globals: this);

                // 処理中応答なしにならないように、非同期処理で実行する
                await Task.Run(() => CSharpScript.RunAsync(code: code, options: options, globals: this));

                // 出力結果
                // called Test2("hello!") in inside.
                // called Test2("hello!2") in inside.
                // called Test1("C:Sample\test.cs") in outside.


            }
            catch (CompilationErrorException ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        // public じゃないと呼び出せない
        public void Test1(string value)
        {
            Console.WriteLine($@"called Test1(""{value}"") in outside.");
        }
    }
}