咱們在學習C#的時候一般都會多多少少接觸ILDasm和Reflector,這兩樣工具讓咱們對C#的理解不會只停留在編譯器這個層面html
上,而是讓咱們更深刻的穿透編譯器。這篇也是但願對IL和Reflector不是很瞭解或者懶的瞭解的同窗可以重視起來,一樣這篇我仍是dom
以QA的形式來告知這兩樣工具的強大和必要性。函數
Q:接口中只能存在方法嗎?工具
A: 這個問題,若是你對IL不熟悉的話,你可能會認爲是錯的,你可能會天真的認爲,記得不錯的話,屬性好像也能夠定義在接口中,事學習
件好像也能夠定義在接口中,字段可不能夠就不知道了,好吧,咱們看下IL,究竟是怎麼樣的。spa
1 public interface IFly 2 { 3 bool CanFly { get; set; } 4 5 event Action ActionFly; 6 }
而後咱們再看看IL,會發現 「屬性」 其實GetXXX/SetXXX方法,「事件」其實就是 Add_XXX/Remove_XXX方法,3d
固然還有一個 「索引器」,本質上也是 get_Item/set_Item 這個配對方法,看完這三個屬性以後,可能有些人會想來出來還有一個code
「構造函數」,本質上它也是方法,可是確不能定義在接口中,固然這個就不是IL的事情的,而是OO定義的問題了,由於接口定義的視頻
目的是規範,而ctor是初始化類,屬於類的一種實現,而接口的規範就是隻能提供方法的定義,不能提供方法的實現,如今咱們再看htm
一下,字段是否能夠定義在接口中?
從截圖中能夠清楚的看到,「接口不能包含字段」的error信息,好了,到如今咱們能夠總結一句話就是,接口中只能定義除構造函數
以外的方法,這個例子展現IL對咱們分析問題的重要性。
Q:Random.Next爲何屢次New以後,會出現重複?
static void Main(string[] args) { for (int i = 0; i < 1000; i++) { var rand = new Random(); Console.WriteLine(rand.Next()); } Console.Read(); }
A: 這個問題問的好,要想知道爲何,咱們得必定要用Reflector來反編譯下Random類的代碼,到底裏面是怎麼實現的,要知
其然,還要知其因此然,下面咱們來看看反編譯後的代碼。
從next函數中的定義能夠看出,其實return 的num值取決於seedArray,那麼咱們下一步看看seedArray究竟是怎麼玩起來的。
經過代碼,咱們能夠找到其實就是在ctor裏面作的。
咱們能夠看到這個for循環,大概看下代碼意思,能夠看出第一個for是給seedArray灌值,第二個for是取下標就是求餘,而後-=操做
來讓SeedArray中的值更加的混亂,反正大致意思就是SeedArray中的值比較亂,比較隨機,而後咱們的next就是經過inext和inextp
取SeedArray值,從而形成隨機數,這個不難看出,隨機的源頭就是咱們給過去的Seed值,而後咱們看到inext和inextp都是++操做,
因此咱們屢次next操做以後,這就保證咱們取數永遠都是隨機的,而若是源頭的Seed同樣的話,就會致使return的值一直重複。
此次咱們把Random放到for循環以外再看看,由於inext和inextp是經過++操做來獲取SeedArray的值來儘量的避免重複。
1 static void Main(string[] args) 2 { 3 var rand = new Random(); 4 5 for (int i = 0; i < 1000; i++) 6 { 7 Console.WriteLine(rand.Next()); 8 } 9 Console.Read(); 10 }
請猛擊視頻教程:http://t.cn/RPtyOFp