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."); } } }