之前有個兄弟給我的卷一re了帖子,我當時沒有g,m,直到他把它刪掉才后悔莫及,人生最痛苦的事情莫過于此。。。。。。
好,即便如此,我們還是滿懷希望的向前奔去。接著寫卷二。
還要提一下,上次最后說到的delegate,在我了解了它的實現和用途以及看到我的偶像的一些訪問記錄后,我對它有了很深的理解,并且在事件處理機制上,我更偏向于我偶像這邊,有兄弟說MFC是switch,java是listener,其實java這些listener在processEvent里面還不是一個個switch然后調用,都是switch,那switch就不能說是特點了,最大的特點還是是否直接使用函數指針來進行響應這點上。往下又說信號處理,以前的8259A發生中斷查中斷向量表進行到頭來也是地址轉移阿,這也沒特點,到后來調用都是地址轉移,而速度的差別就在于在同樣不可避免具有某些相同層次實現的情況下,機制不同架構不同造成的效率差別,這就完全取決于實力了。
1,internal與protected,private
C#默認的,當定義一個class的時候,如果你沒有加任何訪問修飾子,那么該class的訪問權限即為internal,當然你可以顯式制定為internal。internal是什么呢?internal就是說在當前工程中,都可訪問,不管你自己用了幾個名稱空間,都無所謂。
但是在定義一個class中的成員變量的時候,假如你什么都不寫,那么這個成員變量默認的權限就是private。如果你要這個成員在當前工程中也可以被訪問,則必須使用internal關鍵字來顯式的修飾它。
另外,c#里面的protected訪問權限仍然和以前的c++中是一致的含義,表示只有繼承者才有訪問權限。即便是同一個工程,同一個名稱空間中的別的類,都別想看到這個protected成員,頗為嚴格的一個訪問限制。
internal和protected基本控制訪問是在不同的領域,他們兩個是可以同時用來修飾一個對象的。比如
}
這跟java是截然不同的,其實我本可以完全不提java,但由于我自己的背景和一個通盤概括,我還是把java的拿出來與c#進行類比。畢竟本文標題是“特別之處”,當然,這里我也不知道你會認為是c#特別,還是java特別了。
java中沒有完全相同于這個internel似的訪問控制,它有一種獨特的package訪問控制。不管是類還是類的成員,如果你不寫訪問修飾,那么它就是package訪問級別的,package訪問級別的含義是在本package中都可以訪問。java中沒有那種類似internal的“在本工程”或者本“jar”中可以訪問的這種級別,只有package級別。
而java中的protected也是比c#中的protected要寬容得多,java中的protected的含義其實等價于c#中的protected并上java中的package。有人打了這么一個比方,說大宅門,有很多資源都是protected的,這些資源不但可以造福四鄰(同在一個package中),還可以給自己的兒子阿,孫子阿(兒子孫子通過繼承得到資源)即便他們遠走他鄉。
2,enum
我們學過C,C中定義enum中的元素符號的時候,這個符號不能夠與當前作用域中的其他符號相同,并且,所有這些enum中的符號可以直接拿來當常數使用,就好像是#define了一個整形常量一般。特別是當不制定enum類型標記的時候,那簡直就是個#define。
C++中幾乎與C中相同,不同的是,當定義一個這種enum對象的時候,不用
寫 enum 類型標記 對象;
而只用寫 類型標記 對象; 即可。
就好像以前必須寫 struct 類型標記 對象;
而在c++中就可以只用寫 類型標記 對象; 一樣但是不管是在c#或者是java中,首先它們都不可以省略類型標記。其次,不用確保必須不同于同個作用域的其他標記符。再者,不可以直接把enum中的元素符號直接拿過來當常量。起碼也要寫,類型標記.元素符號 才行。
比如
我們在java中比較兩個字符串是否相等用的是"hello".equals(aaa);
但是在c#中,string對象的==運算已經被強行重寫,它就是表示equals,
這就是說,在c#中,實現字符串值比較的話,只需要寫成"hello"==aaa就行了,
這樣設計的目的是為了更直觀。
4.傳引用
在java中有個非常經典的問題,這個問題的到訪真是讓我習以為常。
那就是字符串處理函數的問題。
在java或者c#中,有人
也就是說a+"asdfdjkf"這個東西是一個全新的東西,如果寫成a+="asdfj"或者a=a+"sdfjk"那么原來的a和這個"asdjf"就可以被GC了。
再說java和c#中的對象型別,java和c#中所有的對象型別都是ref型別,也就是說。
String a="dkfjsdf";的時候,在受控堆上生成一個對象"dkfjsdf",然后返回這個對象的ref給a。
我們再看剛才那個字符串處理,a只是一個類似局部變量的形式參數,你將a的ref設為一個新值,然后函數返回,形式參數a沒了,原來的實際參數啥變化都沒有。
但是你說,我就是要這樣處理,這么辦呢?在java中,就沒法這樣處理String,不過StringBuffer之類的倒是可以,因為我們雖然無法改變實際參數的ref值,但是卻可以通過相同值ref更改對象內部成員,對于immutable的我們沒辦法,但對于mutable的我們就可以捏了。
而在c#中,非常恭喜你可以得逞了。就像我們剛才設想的那樣去處理string是可以的,不過要這樣做。
5,out參數
out參數就好像直接通過c#語言實現了com接口定義中的out的語義一樣。
就是輸出參數,我們知道不管是windows api還是com,函數返回值通常用來處理異常的,而真正處理的結果是通過輸出參數帶回的,輸出參數實現有很多種方式,比如傳地址,傳引用,當然com中從來不用c++中詭異的那個&引用。
out參數跟我們之前提到的ref參數唯一不同的就在于,ref參數在填到實參之前,必須初始化,而out參數無此要求,它就是用來帶回結果的,你可以定義一個未初始化的局部變量,然后用out 變量名的寫法填進去,調用完畢,值就放在這個變量里了。
比如我們改改剛才的processString來說明out參數用法
string a;
processString(out a);
Console.WriteLine(a);
新聞熱點
疑難解答