Декомпильнул тут (Решарпером) один из наших небольших классов и по началу его не узнал. Вроде бы в исходниках был малюсенький такой классик. На страничку:
using Nemerle;
using Nemerle.Collections;
using Nemerle.Extensions;
using Nemerle.Text;
using Nemerle.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
namespace N2.Internal
{
[Record]
[StructuralEquality]
public class RecoveryResult
{
public StartPos : int;
public RuleEndPos : int;
public EndPos : int;
public StartState : int;
public StackLength : int;
public Stack : list[RecoveryStackFrame].Cons;
public Text : string;
public FailPos : int;
public BeforeFail : string { get { Text.Substring(0, FailPos) } }
public Skiped : string { get { Text.Substring(FailPos, StartPos - FailPos) } }
public SkipedCount : int { get { StartPos - FailPos } }
public Recovered : string { get { try Text.Substring(StartPos, RecoveredCount) catch "<unknown>" } }
public RecoveredHead : string { get { try Text.Substring(StartPos, RecoveredHeadCount) catch "<unknown>" } }
public RecoveredTail : string { get { try Text.Substring(GetRuleEndPos(), RecoveredTailCount) catch "<unknown>" } }
public RecoveredCount : int { get { EndPos - StartPos } }
public RecoveredHeadCount : int { get { GetRuleEndPos() - StartPos } }
public RecoveredTailCount : int { get { EndPos - GetRuleEndPos() } }
GetRuleEndPos() : int { if (RuleEndPos < 0) StartPos else RuleEndPos }
public override ToString() : string
{
$<#$(Stack.Head) StartState=$StartState Skiped="$Skiped" Recovered: Head="$RecoveredHead" Tail=="$RecoveredTail" #>
}
}
}
А в результате получилось (и ведь не выбросишь не капли):
// Type: N2.Internal.RecoveryResult
// Assembly: N2.Runtime, Version=896.0.0.0, Culture=neutral, PublicKeyToken=e080a9c724e2bfcd
// MVID: 6EF974BD-7AC2-4A0B-94B4-C3222EE7A587
// Assembly location: G:\P\Nitra\N2\N2.Runtime\bin\Debug\N2.Runtime.dll
using Nemerle.Core;
using Nemerle.Internal;
using System;
using System.Collections;
using System.Collections.Generic;
namespace N2.Internal
{
public class RecoveryResult : IEquatable<RecoveryResult>, IStructuralEquatable
{
public readonly int StartPos;
public readonly int RuleEndPos;
public readonly int EndPos;
public readonly int StartState;
public readonly int StackLength;
public readonly list<RecoveryStackFrame>.Cons Stack;
public readonly string Text;
public readonly int FailPos;
public string BeforeFail { get { return this.Text.Substring(0, this.FailPos); } }
public string Skiped { get { return this.Text.Substring(this.FailPos, checked (this.StartPos - this.FailPos)); } }
public int SkipedCount { get { return checked (this.StartPos - this.FailPos); } }
public string Recovered
{
get
{
string str;
try
{
str = this.Text.Substring(this.StartPos, this.RecoveredCount);
}
catch (Exception ex)
{
str = "<unknown>";
}
return str;
}
}
public string RecoveredHead
{
get
{
string str;
try
{
str = this.Text.Substring(this.StartPos, this.RecoveredHeadCount);
}
catch (Exception ex)
{
str = "<unknown>";
}
return str;
}
}
public string RecoveredTail
{
get
{
string str;
try
{
str = this.Text.Substring(this.GetRuleEndPos(), this.RecoveredTailCount);
}
catch (Exception ex)
{
str = "<unknown>";
}
return str;
}
}
public int RecoveredCount { get { return checked (this.EndPos - this.StartPos); } }
public int RecoveredHeadCount { get { return this.GetRuleEndPos() - this.StartPos; } }
public int RecoveredTailCount { get { return checked this.EndPos - this.GetRuleEndPos(); } }
[RecordCtor]
public RecoveryResult([MappedMember("StartPos")] int startPos, [MappedMember("RuleEndPos")] int ruleEndPos, [MappedMember("EndPos")] int endPos, [MappedMember("StartState")] int startState, [MappedMember("StackLength")] int stackLength, [MappedMember("Stack")] list<RecoveryStackFrame>.Cons stack, [MappedMember("Text")] string text, [MappedMember("FailPos")] int failPos)
{
this.StartPos = startPos;
this.RuleEndPos = ruleEndPos;
this.EndPos = endPos;
this.StartState = startState;
this.StackLength = stackLength;
this.Stack = stack;
this.Text = text;
this.FailPos = failPos;
}
public static bool operator !=(RecoveryResult first, RecoveryResult second)
{
return !(first == second);
}
public static bool operator ==(RecoveryResult first, RecoveryResult second)
{
if ((object) first != null)
return first.Equals(second);
return (object) second == null;
}
public int GetHashCode(IEqualityComparer _comparer)
{
return this.GetHashCode();
}
public bool Equals(object other, IEqualityComparer _comparer)
{
return this.Equals(other);
}
public override int GetHashCode()
{
int num1 = 0 + this.StartPos;
int num2 = num1 + (num1 << 10);
int num3 = (num2 ^ num2 >> 6) + this.RuleEndPos;
int num4 = num3 + (num3 << 10);
int num5 = (num4 ^ num4 >> 6) + this.EndPos;
int num6 = num5 + (num5 << 10);
int num7 = (num6 ^ num6 >> 6) + this.StartState;
int num8 = num7 + (num7 << 10);
int num9 = (num8 ^ num8 >> 6) + this.StackLength;
int num10 = num9 + (num9 << 10);
int num11 = num10 ^ num10 >> 6;
list<RecoveryStackFrame>.Cons cons = this.Stack;
int num12 = 0;
if ((list<RecoveryStackFrame>) cons != (list<RecoveryStackFrame>) null)
num12 = cons.GetHashCode();
int num13 = num12;
int num14 = num11 + num13;
int num15 = num14 + (num14 << 10);
int num16 = num15 ^ num15 >> 6;
string str = this.Text;
int num17 = 0;
if (str != (string) null)
num17 = str.GetHashCode();
int num18 = num17;
int num19 = num16 + num18;
int num20 = num19 + (num19 << 10);
int num21 = (num20 ^ num20 >> 6) + this.FailPos;
int num22 = num21 + (num21 << 10);
return num22 ^ num22 >> 6;
}
public override bool Equals(object other)
{
object obj = other;
if (obj is RecoveryResult)
return this.EqualsImpl((RecoveryResult) obj);
else
return false;
}
public bool Equals(RecoveryResult other)
{
return this.EqualsImpl(other);
}
private int GetRuleEndPos()
{
if (this.RuleEndPos < 0)
return this.StartPos;
else
return this.RuleEndPos;
}
public override string ToString()
{
string[] strArray = new string[10];
int index1 = 0;
string str1 = Convert.ToString((object) this.Stack.Head);
strArray[index1] = str1;
int index2 = 1;
string str2 = " StartState=";
strArray[index2] = str2;
int index3 = 2;
string str3 = Convert.ToString(this.StartState);
strArray[index3] = str3;
int index4 = 3;
string str4 = " Skiped=\"";
strArray[index4] = str4;
int index5 = 4;
string str5 = Convert.ToString(this.Skiped);
strArray[index5] = str5;
int index6 = 5;
string str6 = "\" Recovered: Head=\"";
strArray[index6] = str6;
int index7 = 6;
string str7 = Convert.ToString(this.RecoveredHead);
strArray[index7] = str7;
int index8 = 7;
string str8 = "\" Tail==\"";
strArray[index8] = str8;
int index9 = 8;
string str9 = Convert.ToString(this.RecoveredTail);
strArray[index9] = str9;
int index10 = 9;
string str10 = "\" ";
strArray[index10] = str10;
return string.Concat(strArray);
}
protected virtual bool EqualsImpl(RecoveryResult other)
{
if ((object) other == null)
return false;
else
return this.FailPos == other.FailPos && (string.Equals(this.Text, other.Text) && (EqualityComparer<list<RecoveryStackFrame>.Cons>.Default.Equals(this.Stack, other.Stack) && (this.StackLength == other.StackLength && (this.StartState == other.StartState && (this.EndPos == other.EndPos && (this.RuleEndPos == other.RuleEndPos && this.StartPos == other.StartPos))))));
}
}
}