ILSpy 的操作介面有點像 .NET Reflector,雖然功能比較少一點,但基本上還算夠用。就 open source 軟體而言,其實挺不錯的。如果不想花錢買 .NET Reflector,不妨試試 ILSpy。
[2012-01-04 更新]
用這段簡單的 LINQ 範例來比較 ILSpy 和 Reflector 反組譯成 C# 的差異:
public void Linq1() { int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var lowNums = from n in numbers where n < 5 select n; Console.WriteLine("Numbers < 5:"); foreach (var x in lowNums) { Console.WriteLine(x); } }
使用 Reflector 反組譯的結果:
使用 ILSpy 反組譯的結果:
就這個例子而言,程式語法並沒有太大差異。不過,ILSpy 開發社群的部落格上有一篇文章,是 2011 年 4 月發表的,裡面提到:
We're now close to supporting all features in C# 3.0, the only major missing item is expression tree support. So LINQ queries currently decompile into query syntax only if they're compiled into delegates (LINQ-to-Objects, Parallel LINQ), not if they're compiled into expression trees (LINQ-to-SQL etc.).所以,目前的 ILSpy 1.0 版尚未支援 expression tree。根據官網的說法,這部分將於 2.0 版實現。
在我的文章Visual Basic for Reflection(http://blog.kkbruce.net/2011/09/visual-basic-reflection-2.html#.TwFlHflu6pQ)中有提到一套Telerik JustDecompile,目前是免費使用,功能不比 .NET Reflector,提供給你參考。
回覆刪除功能不比 .NET Reflector差 <-- 少了一個字
回覆刪除Thanks :)
回覆刪除我小試了一下
回覆刪除ILSpy反組譯後的內容與原程式碼相去較遠
而.NET Reflector較接近
尤其是程式碼中若包含Linq語句
ILSpy反組譯後的結果幾乎沒有可讀性, 也無法編譯
相較於這點, .NET Reflector表現則優異許多
至於為什麼ILSpy反組譯Linq會讓人看不懂??
因為它拆太細了, 拆到變成Expression Tree
而非標準Linq表達式
感謝 Nicholas 的分享。我針對這部分做了點簡單的測試,並且補充在正文裡。看起來,ILSpy 是支援 LINQ 語法的,但目前並未支援 expression tree,我猜想這可能是你所碰到的狀況。
回覆刪除作者已經移除這則留言。
回覆刪除感謝Huanlin Tsai老師的指正!!
回覆刪除經過我的實驗,果然如同老師所說,單純的Linq是不會有問題的
不過秉持著追根究底的精神
我還原了案發現場
原本程式:
private static void Main(string[] args)
{
var db = new TestDatabaseContext();
var datas = db.People
.Where(r => r.Name == "Angel")
.Select(r => r.Name);
}
.NET Reflector:
private static void Main(string[] args)
{
TestDatabaseContext db = new TestDatabaseContext();
IQueryable datas = from r in db.People
where r.Name == "Angel"
select r.Name;
}
ILSpy:
private static void Main(string[] args)
{
TestDatabaseContext db = new TestDatabaseContext();
IQueryable arg_71_0 = db.People;
ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "r");
IQueryable arg_B1_0 = arg_71_0.Where(Expression.Lambda>(Expression.Equal(Expression.Property(parameterExpression, (MethodInfo)MethodBase.GetMethodFromHandle(ldtoken(get_Name()))), Expression.Constant("Angel", typeof(string)), false, (MethodInfo)MethodBase.GetMethodFromHandle(ldtoken(op_Equality()))), new ParameterExpression[]
{
parameterExpression
}));
parameterExpression = Expression.Parameter(typeof(People), "r");
IQueryable datas = arg_B1_0.Select(Expression.Lambda>(Expression.Property(parameterExpression, (MethodInfo)MethodBase.GetMethodFromHandle(ldtoken(get_Name()))), new ParameterExpression[]
{
parameterExpression
}));
}
這是一段以EF存取DB的範例程式
出現了我所說的情況
所以我猜想也許是EF或是IQueryable造成的
如果跟IQueryable有關
說不定Linq to SQL也會有相同的問題(猜的)
以上
謝謝
我想原因大概就跟正文中最後補充的那段引用官網的文字有關:目前的 ILSpy v1.0 尚未支援 expression tree。由於有些 LINQ to EF 的語法會被 C# 編譯器編譯成 expression tree 的 statement,所以ILSpy 只是老實照翻,而沒有把它逆向轉回原本的簡易語法。這部分的語法支援據說會在 ILSpy v2.0 提供。多謝你的追根究柢 ^^
回覆刪除