3

RegGateのReflectorを使用してアセンブリからソースを回復しようとしています。元のソースは、いくつかのC#3.0機能を利用していたため、回復が少し困難でした。たとえば、ここに匿名タイプの復元されたソースがあります。最初にポップアップするのは、クラス識別子の<>inです。実行時型の命名規則は、設計時の規則よりも明らかに自由です。けっこうだ。簡単な検索と置換で修正されます。他にどのようなコンパイラマングリングに注意する必要があり、どのように対処すればよいですか?

[DebuggerDisplay(@"\{ OverrideType = {OverrideType}, EntityType = {EntityType} }", Type="<Anonymous Type>"), CompilerGenerated]
internal sealed class <>f__AnonymousType1<<OverrideType>j__TPar, <EntityType>j__TPar>
{
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly <EntityType>j__TPar <EntityType>i__Field;
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly <OverrideType>j__TPar <OverrideType>i__Field;

    [DebuggerHidden]
    public <>f__AnonymousType1(<OverrideType>j__TPar OverrideType, <EntityType>j__TPar EntityType)
    {
        this.<OverrideType>i__Field = OverrideType;
        this.<EntityType>i__Field = EntityType;
    }

    [DebuggerHidden]
    public override bool Equals(object value)
    {
        var type = value as <>f__AnonymousType1<<OverrideType>j__TPar, <EntityType>j__TPar>;
        return (((type != null) && EqualityComparer<> <<OverrideType>j__TPar>.Default.Equals(this.<OverrideType>i__Field, type.<OverrideType>i__Field)) && EqualityComparer<<EntityType>j__TPar>.Default.Equals(this.<EntityType>i__Field, type.<EntityType>i__Field));
    }

    [DebuggerHidden]
    public override int GetHashCode()
    {
        int num = -338316509;
        num = (-1521134295 * num) + EqualityComparer<<OverrideType>j__TPar>.Default.GetHashCode(this.<OverrideType>i__Field);
        return ((-1521134295 * num) + EqualityComparer<<EntityType>j__TPar>.Default.GetHashCode(this.<EntityType>i__Field));
    }

    [DebuggerHidden]
    public override string ToString()
    {
        StringBuilder builder = new StringBuilder();
        builder.Append("{ OverrideType = ");
        builder.Append(this.<OverrideType>i__Field);
        builder.Append(", EntityType = ");
        builder.Append(this.<EntityType>i__Field);
        builder.Append(" }");
        return builder.ToString();
    }

    public <EntityType>j__TPar EntityType
    {
        get
        {
            return this.<EntityType>i__Field;
        }
    }

    public <OverrideType>j__TPar OverrideType
    {
        get
        {
            return this.<OverrideType>i__Field;
        }
    }
}
4

3 に答える 3

6

<>それらに含まれる名前によく使用される用語は、言葉では言い表せない名前です-それらは有効なC#ではないためです。これにより、コンパイラで生成されていない名前と衝突するのを防ぎ、C#でそれらを参照しようとするのを防ぎます。

それらを引き起こす可能性のあるいくつかの事柄:

  • イテレータブロックは、それらを実装するためにネストされた型を生成します。

  • 次のような配列初期化子:

    int[] x = new int[] { 1, 2, 3 };
    

    クラスを生成し<PrivateImplementationDetails>{...}ます。(ただし、特定のタイプのみ。)

  • Lambda式は、ロジックを実装するための新しいメソッドと新しいタイプ、および可能な場合はデリゲートと式ツリーをキャッシュするために使用される静的変数を作成する場合があります

  • デバッグ情報をオンにしてコンパイルする場合は、次のようなコレクションおよびオブジェクトの初期化子を使用します。

    List<string> list = new List<string> { "hello", "there" }`)
    Button button = new Button { Text = "Hi" };
    

    言葉では言い表せない名前のローカル変数が生成されます。(これらは、実際の変数への割り当てが行われる前に、プロパティが割り当てられ、アイテムが追加されている間、一時的な値を保持するために使用されます。)

  • C#4の動的コードは、あらゆる種類の奇妙で素晴らしいものを作成します

リフレクター(表示/オプション/逆アセンブラー)で「最適化」レベルを上げると、通常は元のソースコードのようなものを提供するために最善を尽くします-興味深い経験のために最適化をオフにしてください:)

于 2009-11-13T20:58:43.537 に答える
1

変数をキャプチャするラムダは、同様の自動的に作成されたタイプによって表されるクロージャになります。

于 2009-11-13T20:55:21.987 に答える
0

ステートメントを使用するとStatic、VB.Netのキーワードと同様に、コードがわずかに変換されます。

于 2009-11-13T21:00:20.600 に答える