SSCLIクレームの一部の C++ コードに埋め込まれたコメントは、String.Chars プロパティの管理されていない内部実装を参照しています。
この方法は実際には使用されません。JIT は文字列クラスのインデクサー メソッドのコードを生成します。
それで...これは何の魔法のコードですか?ジッターの要点は、さまざまな状況でさまざまなコードが生成されることだと理解しています。しかし、少なくとも最新の x64 Windows 7+ プラットフォームの場合、ジッターはどのようにこれを達成するのでしょうか? それとも本当に秘伝のタレ?
追加の詳細
少し前に、C# で文字列内の個々の文字を反復処理する最速の方法を探していました。安全でないコードに頼ったり、内容を ( 経由で) 複製したりすることのない最速の方法は、実際にはString.Chars プロパティToCharArray()
の呼び出しである組み込みの文字列インデクサーであることが判明しました。最初の質問で、インデクサーが実際にどのように機能するかについて洞察を持っている人がいるかどうかを尋ねましたが、Skeet と Lippert の両方からの衝突にもかかわらず、私はそれについて何の回答も得られませんでした。だから私はそれを自分で掘り下げることにしました:
停止 1: mscorlib
mscorlib.dll を ildasm で調べると、これString::get_Chars(int32 index)
が単なるinternalcall
ポインター (および属性)であることがわかります。
.method public hidebysig specialname instance char
get_Chars(int32 index) cil managed internalcall
{
.custom instance void System.Security.SecuritySafeCriticalAttribute::.ctor() = ( 01 00 00 00 )
} // end of method String::get_Chars
MethodImplOptions 列挙型のドキュメントに記載されているように、「内部呼び出しは、共通言語ランタイム自体に実装されているメソッドへの呼び出しです。」2004 年の MSDN マガジンの記事とSO の投稿の両方で、共有ソース CLIinternalcall
内の ecall.cpp で、管理されていない実装への名前のマッピングを見つけることができることが示されています。
停止 2: ecapp.cpp
ecall.cpp のオンライン コピーを検索すると、次のようget_Chars
に実装されていることがわかりCOMString::GetCharAt
ます。
FCIntrinsic("get_Chars", COMString::GetCharAt, CORINFO_INTRINSIC_StringGetChar)
停止 3: comstring.cpp
comstring.cppには実際に、1219 行目から GetCharAt の実装が含まれています。ただし、前に次のコメントがあります。
/*==================================GETCHARAT===================================
**Returns the character at position index. Thows IndexOutOfRangeException as
**appropriate.
**This method is not actually used. JIT will generate code for indexer method on string class.
**
==============================================================================*/