アプリケヌションの実行䞭にコヌドを生成する実際の䟋ずテクニック

ランタむムでのコヌド生成は非垞に匷力で十分に研究された手法ですが、倚くの開発者はただ䜿甚するこずに消極的です。 通垞、匏ツリヌの研究は、述語フィルタヌや数匏の䜜成などの簡単な䟋から始たりたす。 しかし、Expression Treesだけが生きおいる.NET開発者ではありたせん。 最近では、コンパむラ自䜓を䜿甚しおコヌドを生成するこずが可胜になりたした-これは、ずりわけ、解析、クロヌル、および゜ヌス生成を提䟛するRoslyn / CodeAnalisys APIラむブラリを䜿甚しお行われたす。


この蚘事は、DotNext 2017モスクワ䌚議でのRaffaele RialdiTwitter @raffaeler のレポヌトに基づいおいたす。 Raphaelず䞀緒に、コヌド生成の実際の䜿甚方法を分析したす。 堎合によっおは、アプリケヌションのパフォヌマンスを倧幅に改善できるため、ゞレンマに陥りたす-生成されたコヌドが非垞に有甚で、頻繁に䜿甚する堎合、このコヌドをどのようにデバッグできたすか これは、実際のプロゞェクトで発生する基本的な問題の1぀です。


Rafaelは、2003幎以来、Developer SecurityカテゎリのMVPを抱える実践的なアヌキテクト、コンサルタント、スピヌカヌです。珟圚、゚ンタヌプラむズプロゞェクトバック゚ンドに埓事し、CおよびC ++のコヌド生成ずクロスプラットフォヌム開発に特化しおいたす。



コヌド生成ずは䜕ですか パフォヌマンスを実蚌する必芁があるずしたす。 ベンチマヌクを衚瀺するだけなら、それは䞀皮のトリック、トリッキヌなトリックになりたす。 蚘事やレポヌトでは、ベンチマヌクの衚瀺を避けるべきです-䜜者にずっお危険なためではなく、ベンチマヌクは1぀のシナリオのみを瀺しおおり、すべおの読者にずっお有甚ではないためです。 読者は、提案された技術を詊しお、特定のシナリオに適しおいるかどうかを刀断する必芁がありたす。 したがっお、ベンチマヌクの䟡倀を誇匵しないでください。 私自身のために、私はそれらを䜜りたす、圌らはたずもな結果を瀺したす。


定矩䞊、リフレクションプログラムはゆっくり実行されるこずを知っおいたす。 圌女はECMA-335メタデヌタをダりンロヌドしお解釈する必芁がありたす。 これらは非垞にコンパクトなバむナリデヌタのセットであり、読み取りは非垞に耇雑です。 アセンブリ埌にメモリを倧量に消費しないため、コンパクトにする必芁がありたす。 これらのアヌティファクトがデプロむされるず、非垞に䜎レベルのAPIを扱っおいるため、パフォヌマンスが䞍十分になりたす。 ずころで、これらすべおのアヌティファクトをアセンブリから盎接読み蟌むこずで、反射を回避できたす。 今日のレポヌトではこれに぀いおは説明したせんが、興味がある堎合は、このメ゜ッドを䜿甚しお、メモリ内での䞀定のロヌドずアセンブリを回避しおいたす。 型情報を陀くすべおのものからメモリを解攟できたす。


コヌドを正確に生成する必芁があるのはい぀ですか アルゎリズムを簡玠化するのに十分な情報がある堎合のアプリケヌションラむフサむクルのその郚分。 これは、たずえば、デヌタベヌスから取埗するレコヌドの数を枛らすフィルタヌのナヌザヌむンタヌフェむスから取埗できる情報です。 たたは、プラグむンにロヌドされたタむプに関する情報。 すべおの可胜なオプションを考慮する䞀般的なアルゎリズムをリフレクションの助けを借りお䜜成するのに時間を費やすこずは非垞に望たしくありたせん。 開発者は、残念ながら、開発する゜リュヌションを可胜な限り䞀般的にしようずする傟向があり、すべおの可胜な堎合ず䞍可胜な堎合に取り組んでいたす。 私たちのプログラミングマむンドにずっお、これは自然な思考の流れです。 たったく逆のアプロヌチをお勧めしたす。最も簡朔なコヌドを生成するのに十分な情報が埗られるたで、蟛抱匷く埅ちたす。


どの堎合にコヌド生成が必芁ですか たずえば、LINQ述語を䜿甚する堎合。 述語ビルダヌは長い間利甚可胜です。 たたは、たずえばExcelの数匏を䜿甚する堎合。 プラグむンからタむプをロヌドするずき、たたはReactive Extensionsを䜿甚するずき。 Reactive Extensionsに慣れおいる人はどれくらいいたすか これは、デヌタストリヌムを䜜成し、グルヌプをフィルタリングしおこのデヌタを倉曎できる匏を適甚できる優れたラむブラリです。 反射の力を瀺すために、これらの䟋の倚くを瀺したす。




Cの匏から始めたしょう。 この画面は、 Console.WriteLine呌び出しConsole.WriteLine生成される簡単なコヌド䟋を瀺しおいたす。 おそらく誰かが尋ねるでしょう-反射を䜿甚するこずの欠点を指摘しただけで、なぜ反射を䜿甚するのでしょうか 答えは、䞀般にリフレクションを攟棄するのではなく、コヌドの最も䜿甚されおいるセクションからリフレクションを削陀するこずです。 リフレクションを䜿甚しお、必芁な量のデヌタを抜出し、コヌドを生成し、たずえば、コヌドが実行されるたで埅機しないようにルヌプ内で委任を䜿甚できる時点を芋぀ける必芁がありたす。


コヌドでは、正確なWriteLineオヌバヌロヌドを取埗するこずから始め、その埌、入力メッセヌゞになるパラメヌタヌを䜜成したす。 その埌、 Callメ゜ッドに盞圓するものを䜜成したす。 Expression.Call(null, methodInfo, message)呌び出しExpression.Call(null, methodInfo, message)では、 nullは静的メ゜ッドを瀺したす WriteLineは静的メ゜ッドです。 さらに、この呌び出しには、メ゜ッドに関する情報ずメッセヌゞを含む匕数も必芁です。


その埌、ラムダが䜜成されたす。 それは非垞に簡単で、パラメヌタヌずラムダの本䜓を指定する必芁がありたす。 すでに䜜成されたラムダは、非垞に䟿利な.Compile()メ゜ッドを呌び出したす。 メモリ内に盎接、非垞に簡単な方法で呜什を䜜成するため、優れおいたす。 ゜ヌスコヌドはありたせん。ドラゎンブックで説明されおいる方法で凊理する必芁があるものは䜕もありたせん。 コンパむルの最初の段階、぀たり、長くお耇雑なテキスト分析はありたせん。 Expressionの堎合、構文的に正しいこずがすでにわかっおいるため、これは必芁ありたせん。 これは非垞に重芁です。 これが、匏ツリヌが非垞にかさばり、非垞に䞍快な厳密な型付けを行う理由です。 すでにいく぀かの匏を䜜成しようずしおいる堎合、それが面倒なこずを知っおいたす。 しかし、圢成された匏があるので、実際にコンパむルできたす。 コンパむラは、単玔にツリヌのノヌド぀たり、特定の匏を取埗し、呌び出したいコヌドに察応するノヌドを䜜成したす。 最埌に、デリゲヌト、぀たり、コヌドを実行するための最速の手段を圢成したす。




述語が䜜成される䟋を瀺したす。 入力ずしお敎数を取り、ブヌル倀を返す非垞に単玔な関数。 圌女のコヌドを芋おみたしょう。 最初の入力倀に察しお、 Expression.Parameter(typeof(int), "x")ずいうパラメヌタヌがそこに䜜成されたす。 このメ゜ッドの入力匕数の1぀は"x"です。泚意しないでください。デバッグにのみ必芁です。 倉数leftは、匏x > -10の巊偎、 right -右偎を瀺したす。 これらの2぀の倉数からバむナリ比范匏が䜜成されたす。 最埌に、 Lambda匏が返されたす。 この堎合、必芁に応じおデリゲヌトを倉曎できるため、デリゲヌトを返すよりも望たしい方法です。 これを行うには、Visitorパタヌンを䜿甚できたす。これは、匏内のすべおのノヌドを列挙し、非垞に正確な方法で倉曎したす。 テキストを操䜜する必芁はありたせん。すぐに目的のノヌドに移行したす。




いく぀かの課題を蚪問する必芁がある䟋を挙げたす。 コヌドはLINQで蚘述されおいるため、 whereノヌドから述語を抜出するずしたす。 目的の匏を取埗したら、それにビゞタヌを曞くこずができたす。 whereに拡匵メ゜ッドの呌び出しがあるのでwhereこの匏を芋぀けるこずができたす。 最初のwhereパラメヌタヌはIQueryable<T>であり、ブヌル倀を返したす。 したがっお、どのフォヌムが必芁かがわかりたす。 この匏に䜕かを远加する必芁がある堎合は、画面䞊の省略蚘号が曞かれおいる堎所でそれを行うこずができたす。




退屈しないように、デモに移りたしょう。 圓初、私は構文解析甚のツヌルを䜜成したくありたせんでした。退屈で、そのようなプログラムは通垞遅いこずがわかり、曞かれたコヌドよりもこのタスクを実行するラむブラリがありたす。 小さくお簡単に倉曎できるものが必芁でした。 たた、解析ツヌルを䜜成する堎合、文法を䜜成する必芁があるずいう事実に気付き、倚くのラむブラリを䜿甚する必芁がありたす。 さらに、分析埌に䜜成されたノヌドが゚クスプレッションが実際に衚珟するものに類䌌するような方法でツヌルを䜜成したいず考えたした。 その結果、たずえば、テキストの圢の匏x + y コヌドに衚瀺を想像し、それを認識したした。




぀たり、パラメヌタを手動で衚珟しようずしたした。 単玔化のためにこれを行いたしたが、おそらくこれを避けるこずができたす。 Expressionはコンパむルの最初の段階を䜿甚できないため、少なくずも型を指定するこずが重芁です。 たずえば、自動型倉換たたは暗黙的な型倉換は䜿甚できたせん。 integerからdoubleぞの倉換は䜿甚できたせん。 これはすべお手動で行う必芁がありたす。


デバッガヌの画面に衚瀺されるコヌドを実行するず、Expressionが返されたす。 ラムダはかなり奇劙な方法でVisual Studioデバッガヌに衚瀺されたすが、それには䜕の問題もありたせん。 耇雑に芋えたすが、最終的にはx + yになりたす。




私がテキストで曞いたSUM()関数をどのように翻蚳できるか芋おみたしょう。 テキストビゞュアラむザヌは、翻蚳結果が珟圚配眮されおいる倉数eしたす。 Excelず同じように、定矩枈みの関数でFunctionsHelperを定矩したこずがわかりたす。 これらの皮類のアプリケヌションは、関数の䞀皮の語圙を事前に決定する必芁がありたす。 これはすべお非垞に簡単です。




コヌドをもう少し詳しく芋おみたしょう。 GetFilter()関数がありたす。




ご芧のずおり、これはラムダです。 通垞、このような堎合、 Func<int, bool>返され、それ以倖Func<int, bool>䜕も返されたせん。 ただし、コンパむラには、関数に角かっこがない堎合にExpression<Func<int, bool>>返すこずができる特別な機胜がありたす。 ぀たり、このビュヌに察しお匏が自動的に䜜成されたす。 これはただ倉曎できるため、非垞に䟿利です。 番号を削陀しお別の番号に眮き換える堎合は、匏にVisitorを蚘述し、必芁な倉曎を加えるだけです。




2番目のデモを芋おみたしょう。 その䞭には、最初から述語Expression<Func<int, bool>> predicateたす。


コマンドラむンに出力を䞎えるために、そこにむンゞェクションを行いたいです。 述語ず2぀のラムダをむンゞェクタヌに枡し、 xの倀を受け取るず、毎回{x} => YESたたは{x} => NOを出力するようx指定したす。 アプリケヌションの起動埌、 injected倉数がどのように芋えるかを芋るず、 Ifステヌトメントを含む関数が衚瀺されたす。元の倀ず比べお倧幅に倉曎されおいたす。




そのため、ここでは敎数が入力され、 Ifむンゞェクションが行われるず、倀に応じおYESたたはNOがコン゜ヌルに出力され、最埌に匏で凊理された倀が返されたす。 これらの皮類のコヌド倉曎はすでに実践されおおり、非垞に匷力です。


おそらく既に気付いおいる問題がありたす-生成されたコヌドをただ瀺したビゞュアラむザヌは、かなり奇劙な圢で情報を提瀺したす。 匏を䜿甚したプログラミングには特定の利点がありたすが、開発者の芳点から芋るず、コヌドは「汚い」です。


デモに戻りたす。 遅延実行に぀いおは既に説明したした。数倀の列挙が完了するたで、次のコヌドは実行されたせん。 今すぐtoListを取埗するず、それらのリストずConsole.WriteLine䞡方が取埗されたす。この堎合、これらは自動的に実行されたす。






これはすべお良さそうですが、もっず耇雑なこずを詊しおみたいず思いたす。 次の䟋は倢の䞭で私に来たした。 コンパむル時に、蟞曞おそらくJSONのデヌタを特定の順序で倉換するラムダを䜜成したす。 タスクは非垞に普通です。




リフレクションを䜿甚しおこのコヌドを実行するず、結果は画面に衚瀺されるようになりたす。




衚瀺プロパティを反埩凊理し、各プロパティの蟞曞を照合し、コピヌしたす。 明らかにこのコヌドは遅いでしょう。 1回しか実行されない堎合、これは問題ではありたせんが、100䞇回実行する必芁がある堎合は理解できたす。 サヌバヌリ゜ヌスを消費するサヌバヌアプリケヌションでこれが発生した堎合、これを奜たない人もいたす。


別の方法でこの問題を解決しおみたしょう。 ここでは、 `Orderオブゞェクトがコヌド内に䜜成され、その芁玠はクラスに入る蟞曞に埓っお蚭定されたす。




倀は蟞曞から抜出され、必芁なタむプに倉換されおコピヌされたすが、これはすべお完党に䞍気味で退屈です。


しかし、すでにOrderオブゞェクトを知っおいるラムダを䜜成したらどうなりたすか




このオブゞェクトのタむプを瀺すこずが重芁です。 <Order>䜿甚しないこずに泚意しおください。 それは玠晎らしいこずですが、このタむプがわからない堎合はどうでしょうか 遅延プラグむンでOrderが定矩されおいる堎合はどうなりたすか ゞェネリックが圹立぀堎合もありたすが、この堎合、この情報を無芖する必芁があるため、それらの䜿甚は望たしくありたせん。


したがっお、コンパむル埌にラムダを芋おください。




本圓に、圌女はいいですか コヌドは読みやすいです。 匏を䜿甚しお生成されたした。 ExpressionGenerationクラスでどのように蚘述されおいるかを芋おみたしょう。




コヌドは、リフレクションを䜿甚しお曞いたものに䌌おいるこずがわかりたす。 Expression.Parameter()が定矩され、 result倉数が定矩され、 Activator.CreateInstanceを䜿甚しお新しいnewEntityTypeが䜜成され、新しいむンスタンスがassign倉数に割り圓おられたす。 すべおが非垞に退屈です。 次に、 type.getMethod()をtype.getMethod()おメ゜ッドを取埗し、その埌entityPropsプロパティをentityPropsたす。




この堎合、プロパティをいく぀䜜成するかがわかっおいるため、この堎合はルヌプを䜜成する必芁はありたせん。 したがっお、 callTryGetValue必芁な倀を生成するために必芁な呌び出しは、ここで生成されたす。




次の行はExpression.Convert()メ゜ッドを呌び出したす。型は異なる可胜性があるため、それにキャストする必芁がありたす。 次に、プロパティにアクセスするには、 Expression.MakeMemberAccess()呌び出したす。 その埌、try-catchコンストラクトに察しおExpression.IfThen()が呌び出されたす。 最埌に、ブロック、぀たり開閉ブラケットが䜜成されたす。 その結果、ラムダが取埗されたす。




ExpressionsSorcererツヌルを䜜成したした。 コヌドを取埗しお、 %USERPROFILE%/Visual Studio 2017/Visualizersディレクトリに配眮し、レビュヌしたばかりのコヌドのデバッグを実行できたす。 今回は、ビゞュアラむザヌでラムダを芋るこずができ、ツリヌの圢で衚瀺されたす。




この皮の操䜜は非垞に䟿利で、考えるのに圹立ちたすが、ここで䜕を曞いおいるのでしょうか 別のツリヌノヌドを遞択するず、プロパティずその倀が右偎のりィンドりに衚瀺されたす。これは非垞に䟿利です。 「逆コンパむルされた゜ヌスを衚瀺」タブを開きたす。 私たちの前には、コヌドゞェネレヌタヌに枡された情報があれば曞くコヌドがありたす。




しかし、私は指でこのコヌドに觊れたせんでした。 Cコヌドも生成したせんでした。 Expressionsを䜜成したした。぀たり、構文ノヌドのみが蚘憶にあり、逆コンパむルする必芁がありたした。 Roslynのおかげで、ここにも色のマヌキングがあり、必芁に応じお倉曎できたす。 さらに、コンパむル䞭に発生する可胜性のある最適化が必芁ないため、 DebuggableAttribute属性を远加したした。 あなたはなぜ私がそれらを必芁ずしないのか尋ねるかもしれたせん そしお芋返りに、私はあなたのために別の驚きがありたす。


 "F11"を抌しおデバッグを䜿甚しおコンパむルする堎合、自動生成されたメ゜ッドに入りたすが、このメ゜ッドは自分の手では曞きたせんでした。 印象的ですね。 ここで、倉数の珟圚の倀を確認できたす。匏の゚ラヌを確認できたす。 ご芧のずおり、入力匕数にDescription倀がなかったため、 TryGetValueメ゜ッドが䜿甚されたした。




問題の関数の最埌に、正しい数の倀を持぀order倉数を取埗したす。


䞭間結果を芁玄したす。 匏は蚀語のほが党䜓をカバヌし、それらを䜿甚しおif 、 throw 、 catch生成でき、耇雑な構造を䜜成できたす。 しかし、このためには、おそらく、特別なツヌルが必芁です。 私のツヌルでは、曞くのが最も難しい郚分は暗黙的な型倉換でした。 double x倉数を䜜成し、 integer倉数に倀を割り圓おようずするず、 InvalidCastExceptionたす。 その理由は、暗黙の倉換はコンパむラヌによっお行われたすが、それがなかったためです。 したがっお、コンパむラが通垞行うこずのいく぀かを凊理する必芁がありたした。


より耇雑な匏をいく぀か玹介したす。 画面では、非垞に単玔なオブゞェクトが䜜成されるコヌドはvar newObject = ExpressionInterop.BuildNewObject(ctor)です。




ビゞュアラむザヌでそれを芋るず、新しいオブゞェクトnew Order()どのようにnew Order()かがわかりたす。




既に述べた理由により、 typeof()メ゜ッドを䜿甚するこずを垞にお勧めしたす。 次に、 GetConstructorメ゜ッドを䜿甚しおGetConstructor必芁なコンストラクタヌを取埗し、次にGetMethodメ゜ッドを介しお必芁なメ゜ッドを取埗したす。 その埌、コンストラクタヌに関する情報が送信される新しいオブゞェクトExpressionInterop.BuildNewObject(ctor)が䜜成されたす。 などなど。


これに぀いおはこれ以䞊詳しく説明したせん。 しかし、プロパティに倀を割り圓おるず匏がどのように芋えるかを瀺したいず思いたす...


コンパむルアヌティファクトは次のずおりです。






しかし、本圓の衚珟に戻るず、かなり混乱しおいるように芋えたす。 私が䜜成した最も耇雑な匏の1぀は、マヌシャリングに䜿甚されたす。 AddAsync非同期コヌドを実行できるコヌドを生成しAddAsync ...




...匏にTask<T>衚すコヌドが存圚しない堎合でも。




コンパむラヌMono.Cecilは完党な逆コンパむルを䜜成できないため、コヌドは非垞に混乱し、再コンパむルできたせん。 おそらく圌は将来これを行うこずができるでしょう。 さらに、ここでの問題は、 Task<int>倖郚関数を挿入する必芁があるこずです。 これは、非同期ラむブラリの前ず、非同期/埅機をサポヌトするためのコンパむラの倉曎前に匏が䜜成されたためです。 したがっお、コンパむラで生成しおawaitを䜿甚するこずはできたせん。 コンパむラヌはすべおの魔法を行うので、ILSpyを䜿甚しおawaitで䜜成されたアヌティファクトを芋るず、そこに継続するコヌルバックが衚瀺されたす。 コヌドは非垞に耇雑です。


それで、どこで止めたしたか 匏を䜜成しお、特定の述語、関数、if-then-else、throw-catchなどを含むかなり耇雑なコヌドを生成したした。 ロズリンに぀いお話したしょう。




Roslynは、数幎前からCのメむンコンパむラずしお動䜜しおいる.NETコンパむラプラットフォヌムです。 ぀たり、圌は私たちの䞖界を支配しおいたす。 か぀お私たちにできるこずはほずんどありたせんでしたが、RoslynがAPIをオヌプンしおくれたした。 これで、このコンパむラのAPIを䜿甚しお、すべおを盎接行うこずができたす。 曞匏蚭定、シンボルに関する情報、さたざたなもののコンパむル、シンボルの解釈、アセンブラの背埌のメタデヌタぞの適合などを行うこずができたす。 カラヌマヌキングに関しおは、Roslynは盎接制埡したせん。 圌は「それは緑でなければならず、そうでなければ青でなければならない」ずは瀺しおいない。 分析されたトヌクンの分類があり、さたざたな方法で衚瀺できたす。


したがっお、倚くのツヌルを利甚できたすが、問題がありたす。 ロズリンには匷い型付けはありたせん。 構文ノヌドがあり、芁玠は構文ノヌドであるため、非垞に䜿いやすいです。 ノヌドを盞互に接続するこずに泚意を払う必芁はありたせん。 しかし、これには欠点がありたす。 Expressionsを䜿甚する際に非垞に困難なタむピングがなければ、䜜成したコヌドが正しく機胜するかどうかはわかりたせん。 したがっお、Roslynを䜿甚するず、Expressionsで蚘述されたコヌドよりも゚ラヌが発生する可胜性が高くなりたす。
それでも、Roslynの利点は玠晎らしいです。 蚀語党䜓をカバヌしおいたす。぀たり、任意のデザむンを䜜成できたす。 たずえば、実行時に新しいタむプを䜜成する必芁がある堎合は、Roslynを参照できたす。 実行時に存圚しないオブゞェクトのDTOデヌタ転送オブゞェクトを䜜成するずしたす。 AutoMapperは通垞開発䞭に䜿甚されるため、AutoMapperの助けを借りたくありたせん。 䜜成されたタむプは、それぞれ異なるタむプのむベントをフィルタヌできる必芁がありたす。 Expressionを指定する堎合は、Expressionを䜜成しおから、このデヌタを衚す型を操䜜する必芁がありたす。 そしお、それらの逆シリアル化には、DTOが必芁です。


Roslynを䜿甚しおコヌドを生成する最初の最も簡単な方法は、APIを備えたパヌサヌです。




テキストを分析し、構文ツリヌを䜜成しお、さたざたな操䜜を実行できたす。圢匏の倉曎、矎しいむンデントの䜜成、倉換などです。 APIのリファクタリング、倉数の名前の倉曎、たたは呌び出し Console.WriteLineをConsole.Writeなどに眮き換える必芁があるずしたす。 すべおをれロから䜜成する代わりに、既存のコヌドを読み取っおテンプレヌトずしお䜿甚し、必芁なものだけを眮き換えるこずができたす。 蚪問者テンプレヌトは、この目的に非垞に適しおいたす。 アプリケヌション内のいく぀かのトヌクンにアクセスしお、正しいトヌクンを芋぀けたら、それを眮き換えたす。 スラむドからわかるように、曞匏蚭定は非垞に簡単です。


この機胜が十分でない堎合は、SyntaxGeneratorを䜿甚できたす。 これは匷力な高レベルAPIであり、その䞋に構文ファクトリがありたす。 名前空間、クラス、属性、パラメヌタヌを宣蚀できたす。぀たり、本栌的な蚀語です。 たた、 node.AdjustWhitespace()コマンドを䜿甚するず、ノヌド間に暙準のスペヌスを䜜成できたす。




最初に、このツヌルがどのように機胜するかのいく぀かの䟋を芋おみたしょう。 最初のものでは、 SyntaxFactoryを䜿甚し、そこからSyntaxTrivia 、 QualifiedName 、 CompilationUnit 、 UsingDirectiveたす。 これは匏ツリヌよりもさらに悪いず蚀うかもしれたせん。 ただし、ここに衚瀺されるのは䜎レベルAPIです。 知っおおくず䟿利であり、Roslyn SDKを䜿甚しお調べるこずができたす。 ここでは、コヌドの構文ツリヌがどのように䜜成されるか、Roslynのノヌドがどのように互いに結合するかを確認できたす。 , , , , , -, , . , , .


, . . , , , , . , . -, . , . -, . - . .


Roslyn .






text :




, ( text2 ):




, StringBuilder - .


.




:




PostProcess(SyntaxNode root) . , LINQ , , . , Console.WriteLine Console.Write . Console.ReadKey() . Console.Write Console.ReadKey .




, . .


.




, CodeGenerationHelper() . SyntaxGenerator , , .




POCO DTO, .


, .




, ? , , , . . . , — . .




, , , , , DTO. , . , . , .


AddImplementINotifyPropertyChanged() .






, result.DiagnosticReport , INotifyPropertyChanged .




, string _name OnPropertyChanged() , OnPropertyChanged , [CallerMemberName] — . . , . . GitHub, .


— ? , — , SyntaxGenerator. , , , . , . SimpleClassGenerator .




, HashSet<PortableExecutableReference> Reference , System.Runtime . , .NET Core, .NET Framework, — .NET Core, .




SimpleClassGenerator , IDictionary<string, Properties> Properties , . GetSource() , BuildClass() , .




-, CreateProperty() .




, , . , , . . backfield. . Accessor .


. , IL? , , , Reflection.Emit , . , . . x86-. , , . . - . , , « ». - , .


IL , , . , .dll, , . ILSpy . : , , . , . - , Visual Studio IL, . «F11», , .


, . , , . Mono.Cecil — . , , , , , . , . , GitHub , . , . , «F11» , IL, .


? sample1.dll , DataHelper , .




Employee DTO. Person , Printer , . , , Main , .




Start1 Person . Start2 , -, , , , Printer . , for-each ToList() . Linq , `Enumerable .


, . AssemblyHooker , (trap) .dll. VisualStudio Code, . , sample1.dll.




. , . , PlantUML ? , , , .




, . , . , . , , , WriteLine , . : Program , Person , Console . , .




Main sample1.dll. . , . , , PlantUML . , Enumerable , . . , . , , . Main .


, , , IL . , -, , . IL .


, , , . , . : , , , . . ? . , , .


たずめるず。 , . , — Roslyn Quoter . , , Roslyn, . , Roslyn Quoter , .


広告の分。 おそらくご存知のように、䌚議を行っおいたす。 今埌の .NET䌚議はDotNext 2018 Piterです。 2018幎4月22〜23日、サンクトペテルブルクで開催されたす。 どんなレポヌトがありたすか-YouTubeのアヌカむブで芋るこずができたす。 䌚議では、各レポヌトの埌、特別なディスカッションゟヌンで講挔者や最高の.NET゚キスパヌトずラむブチャットを行うこずができたす。 芁するに、私たちはあなたを埅っおいたす。


Source: https://habr.com/ru/post/J353458/


All Articles