ハブラチ人への良い一日! 今日、私は偉大で力強いRuslishであなたを苦しめ続けます。 これは記事の続きです。
»
開発→アンマネージコードからの.Netクラスのクロスプラットフォーム使用。 またはLinuxのIDispatchの類似物»
開発→ネイティブVKを介した1Cでの.Netクラスのクロスプラットフォーム使用。 またはLinuxでCOMを置き換える»
ネイティブVKを介した1Cでの.Netクラスのクロスプラットフォーム使用。 またはLinux IIでCOMを置き換える»
.Net Native VKによる1Cの非同期プログラミング1C、Linux、Excel、Word、OpenXML、ADO、およびNet Core現在、.Net Core 2の動的コンパイルオプション
1.これは、Microsoft.CodeAnalysis.CSharp.CSharpCompilation CodeDomの類似物です。
2. Roslyn Scripting API。
ここの例
var compilation = Microsoft.CodeAnalysis.CSharp.CSharpCompilation.Create("a") .WithOptions(new Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary)) .AddReferences( Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location)) .AddSyntaxTrees(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText( @" using System; public class C { public C(){} public string M() { return ""Hello Roslyn.""; } }")); var fileName = @"d:\NetStandart\TestCoreNetApp\src\TestCoreNetApp\bin\Debug\netcoreapp1.0\a.dll"; compilation.Emit(fileName); var a = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromAssemblyPath(fileName); Type = a.GetType("C"); var obj = Activator.CreateInstance(); var res = .GetMethod("M").Invoke(obj, null); Console.WriteLine(res.ToString());
このアプローチは、ライブラリを更新する必要がある場合に適しています。 ただし、これにより、すべての結果を伴うDLLが作成されます。
私がもっと好きな2番目の方法。 デリゲートを取得する例を見てみましょう。
string words = " "; string pattern = @"\w+"; var scr = Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default; var mscorlib = Assembly.Load(System.Runtime.Loader.AssemblyLoadContext.GetAssemblyName(@"c:\Users\Smirnov_SA\.nuget\packages\Microsoft.NETCore.Portable.Compatibility\1.0.1\ref\netcore50\mscorlib.dll")); scr =scr.WithReferences(mscorlib, typeof(MulticastDelegate).GetTypeInfo().Assembly, typeof(System.Runtime.CompilerServices.IStrongBox).GetTypeInfo().Assembly, typeof(MatchEvaluator).GetTypeInfo().Assembly, typeof(Regex).GetTypeInfo().Assembly) .WithImports("System", "System.Text.RegularExpressions"); string = @"return (MatchEvaluator)((match) => { string x = match.Value; // If the first char is lower case... if (char.IsLower(x[0])) { // Capitalize it. return char.ToUpper(x[0]) + x.Substring(1, x.Length - 1); } return x; });"; var result = Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.EvaluateAsync(, scr).Result; MatchEvaluator evaluator = (MatchEvaluator)result; Console.WriteLine(Regex.Replace(words, pattern, evaluator));
以下へのリンクを必ず含めてください:
mscorlib.dll
System.Private.CoreLib.ni.dll
System.Runtime.dll
次のライブラリがコンパイルに使用されます。
「Microsoft.CodeAnalysis.CSharp」:「2.0.0-beta3」、
「Microsoft.CodeAnalysis.CSharp.Scripting」:「2.0.0-beta3」、
「Microsoft.CodeAnalysis.Scripting.Common」:「2.0.0-beta3」、
Microsoft.CodeAnalysis.Scripting
動的コンパイル。 かつて彼は車のスペアパーツを扱っていました。 そして、たくさんのサプライヤーと顧客がいます。 さらに、数百万のポジションの価格。 そして、それぞれが独自の形式でデータを提供します。 各クライアントは、ディレクトリに書き込むコードを作成し、RunまたはCalculateで使用する方が簡単でした。 確かに、百万番目の価格で作業する場合、このアプローチは遅くなりました。
どういうわけか、DLLを作成し、COMで作業する必要がありました。
動的コンパイルを使用すると、コードを保存し、条件に応じて適用できます。 条件によって動的に形成されたものを含め、コンパイルされたデリゲートを再利用のためにキャッシュできます。
コンパイル速度は非常に高速です(5秒を除く)。
1Cに移りましょう。 したがって、2番目の1Cアルゴリズムは次のようになります
= "return (MatchEvaluator)((match) => |{ | string x = match.Value; |// If the first char is lower case... |if (char.IsLower(x[0])) |{ |// Capitalize it. |return char.ToUpper(x[0]) + x.Substring(1, x.Length - 1); |} |return x; | |});"; = " "; = "\w+";
一般的に、特別なことは何もありません。 アセンブリを取得し、それらへのリンクをコンパイルして呼び出しました。
さらに複雑な例に移りましょう。 そのため、前回の記事では、ExcelとWordを読む例を使用してDocumentFormat.OpenXmlを使用する例を示しました。
b関数を介してオブジェクトに文字列をキャストすることで速度に問題があり、1C自体からの呼び出し速度はネイティブコードの5倍遅くなります。
したがって、.Netのほとんどのコードを削除します。 大規模な.Netにも同様のオプションがあります
1Cの.Net。 HTTPClient、AngleSharpの例を使用します。 CSSセレクターを使用したJala承認を含むAngleSharpライブラリーを使用したサイトの便利な解析。 動的コンパイル (記事の最後の例)。
クラスを作成し、レイアウトにコピーします。 クラスの本質は、セルデータを読み取り、行番号でグループ化することです。
public class { public string ; public string ; public int ; public string ; } public class ExcelReader { static Regex = new Regex("[A-Za-z]+"); OpenXmlElementList ; void (string , ) { . = ; var match = .Match(); var = match.Value; var = int.Parse(.Substring(.Length)); . = ; . = ; } void (List<> , Cell cell) { var = cell.CellReference.InnerText; var text = cell.CellValue?.Text; var DataType = cell.DataType; string res = text; if (DataType != null && DataType == CellValues.SharedString) { int ssid = int.Parse(text); res = [ssid].InnerText; } if (res == null) return; var result = new (); (, result); result. = res; .Add(result); } public List<> ReadExcel(string fileName) { List<> = new List<>(); using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fs, false)) { var workbookPart = doc.WorkbookPart;
読み取りクラスについて説明し、ファイルパスを取得して匿名クラスを返すデリゲートへのリンクを返しました。 とにかく、1Cではリフレクションを通して彼と協力します。 ここでは2つのクラスについて説明していることに注意してください。
次に、このコードを1Cから呼び出します。
ScriptOptions=("Microsoft.CodeAnalysis.Scripting.ScriptOptions","Microsoft.CodeAnalysis.Scripting"); CSharpScript=("Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript","Microsoft.CodeAnalysis.CSharp.Scripting"); scr = (ScriptOptions.Default); mscorlib = (.("mscorlib.dll",)); Private_CoreLib=(.("System.Private.CoreLib.ni",)); System_Runtime=(.("System.Runtime",)); RegularExpressions=(.("System.Text.RegularExpressions",)); OpenXml=(.("DocumentFormat.OpenXml.dll")); Linq=(.("System.Linq", )); FileSystem=(.("System.IO.FileSystem", )); Regex=(RegularExpressions.GetType("System.Text.RegularExpressions.Regex")); scr =(scr.WithReferences(mscorlib.(), Private_CoreLib.(), System_Runtime.(), RegularExpressions.(),OpenXml.(),Linq.(),FileSystem.())); scr =(scr.WithImports("System", "System.Collections.Generic", "System.Linq", "System.IO", "DocumentFormat.OpenXml", "DocumentFormat.OpenXml.Packaging", "DocumentFormat.OpenXml.Spreadsheet", "System.Text.RegularExpressions")); =("").(); = ((CSharpScript.EvaluateAsync(, scr.())).Result); = (.DynamicInvoke()); (.); = ; =.; (.,); =.; =(.); =(.(.())); =1;
現在、Excelの処理速度は大幅に向上しており、コンパイルコストはファイルの読み取りコストに見合っています。
Wordを読むプロセスを見てみましょう。 さらに苦労せずに、私は
ここで完成したクラスを取り
ました 。 特にすべてが英語であるため。
しかし、Ruslishに戻ります。
ScriptOptions=("Microsoft.CodeAnalysis.Scripting.ScriptOptions","Microsoft.CodeAnalysis.Scripting"); CSharpScript=("Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript","Microsoft.CodeAnalysis.CSharp.Scripting"); scr = (ScriptOptions.Default); mscorlib = (.("mscorlib.dll",)); Private_CoreLib=(.("System.Private.CoreLib.ni",)); System_Runtime=(.("System.Runtime",)); RegularExpressions=(.("System.Text.RegularExpressions",)); OpenXml=(.("DocumentFormat.OpenXml.dll")); Linq=(.("System.Linq", )); FileSystem=(.("System.IO.FileSystem", )); Regex=(RegularExpressions.GetType("System.Text.RegularExpressions.Regex")); scr =(scr.WithReferences(mscorlib.(), Private_CoreLib.(), System_Runtime.(),OpenXml.(),FileSystem.())); scr =(scr.WithImports("System", "System.Text", "System.IO", "DocumentFormat.OpenXml", "DocumentFormat.OpenXml.Packaging")); =("").(); = ((CSharpScript.EvaluateAsync(, scr.())).Result); = .DynamicInvoke(); = ; .(); .();
主なタスクは、使用されるアセンブリと名前空間への参照を指定することです。
次の記事では、イベントを使用するオブジェクトのラッパーを動的に作成します。
1Cの.NET(C#)。 AddHandlerまたはHandlingExternal Eventsを介して1Cで.Netイベントを使用するためのラッパークラスの動的コンパイル