컴파일러 생성 cruft
-
20-09-2019 - |
문제
Reg Gate의 반사판을 사용하여 어셈블리에서 소스를 복구하려고합니다. 원래 소스는 몇 가지 C# 3.0 기능을 활용하여 복구하기가 조금 어려워졌습니다. 예를 들어 익명 유형의 복구 된 소스가 있습니다. 가장 먼저 튀어 나오는 것은 클래스 식별자의 <>입니다. 실행 시간 유형 명명 규칙은 디자인 시간 규칙보다 더 자유롭습니다. 그럴 수 있지. 간단한 검색과 교체는이를 해결합니다. 다른 컴파일러 맨글 링을 찾아야하며 어떻게 처리해야합니까?
[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;
}
}
}
해결책
이름에 종종 사용되는 용어 <>
그들 안에 말할 수없는 이름 - 유효하지 않기 때문에 c#. 이렇게하면 컴파일러가 아닌 이름으로 충돌하지 않으며 C#에서 참조하려고하지 않습니다.
그들을 일으킬 수있는 몇 가지 :
반복자 블록은 중첩 유형을 생성하여 구현합니다.
다음과 같은 배열 초기화기
int[] x = new int[] { 1, 2, 3 };
a
<PrivateImplementationDetails>{...}
수업. (그러나 특정 유형에 대해서만.)Lambda 표현식은 논리를 구현하기위한 새로운 방법과 새로운 유형을 만들 수 있으며 가능한 경우 대의원과 표현 트리를 캐시하는 데 사용되는 정적 변수
디버깅 정보가 켜져있는 경우, 수집 및 객체 초기화기를 다음과 같은 객체 이니셜 라이저로 컴파일하는 경우
List<string> list = new List<string> { "hello", "there" }`) Button button = new Button { Text = "Hi" };
말할 수없는 이름의 로컬 변수가 생성됩니다. (실제 변수에 대한 할당이 발생하기 전에 속성이 할당되고 항목이 추가되는 동안 임시 가치를 유지하는 데 사용됩니다.)
C# 4의 동적 코드는 모든 종류의 이상하고 멋진 것들을 만듭니다.
리플렉터에서 "최적화"레벨을 켜면 (보기 / 옵션 / 디스 어셈블러) 일반적으로 원래 소스 코드와 같은 것을 제공하기 위해 최선을 다합니다. 흥미로운 경험을 위해 최적화를 끄십시오 :)
다른 팁
변수를 캡처하는 람다는 자동으로 생성 된 유형으로 표시되는 클로저를 초래합니다.
진술을 사용하면 코드가 약간 변환됩니다. Static
vb.net의 키워드.