国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

A Comparative Overview of C#中文版(二)

2024-07-21 02:22:13
字體:
來源:轉載
供稿:網友
在gametest里,我們分別創建了一個game和一個監視game的referee,然后,然后我們改變game的score去看看referee對此有何反應。在這個系統里,game沒有referee的任何知識,任何類都可以監聽并對game的score變化產生反應。關鍵字event隱藏了除了+=和-=之外的所有委托方法。這兩個操作符允許你添加(或移去)處理該事件的多個事件處理器。
【譯注:我們以下例說明后面這句話的意思:
public class game
{
public event scorechangeeventhandler scorechange;
protected void onscorechange()
{
    if (scorechange != null) scorechange(30, ref true);//在類內,可以這么使用
}
,但在這個類外,scorechange就只能出現在運算符+=和-=的左邊】
     你可能首先會在圖形用戶界面框架里遇到這個系統。game好比是用戶界面的某個控件,它根據用戶輸入觸發事件,而referee則類似于一個窗體,它負責處理該事件。
     【作者注:委托第一次被微軟visual j++引入也是anders hejlsberg設計的,同時它也是造成sun和微軟在技術和法律方面爭端的起因之一。james gosling,java的設計者,對anders hejlsberg曾有過一個故作謙虛聽起來也頗為幽默的評論,說他因為和delphi藕斷絲連的感情應該叫他“方法指針先生”。在研究sun對委托的爭執后,我覺得稱呼gosling為“一切都是一個類先生”好像公平些j 過去的這幾年里,在編程界,“做努力模擬現實的抽象”已經被很多人代之以“現實是面向對象的,所以,我們應該用面向對象的抽象來模擬它”。
     sun和微軟關于委托的爭論可以在這兒看到:
http://www.javasoft.com/docs/white/delegates.html http://msdn.microsoft.com/visualj/technical/articles/delegates/truth.asp 】
6.枚舉
     枚舉使你能夠指定一組對象,例如:
聲明:
public enum direction {north, east, west, south};
使用:
direction wall = direction.north;
這真是個優雅的概念,這也是c#為什么會決定保留它們的原因,但是,為什么java卻選擇了拋棄?在java中,你不得不這么做:
聲明:
public class direction
{
    public final static int north = 1;
    public final static int east = 2;
    public final static int west = 3;
    public final static int south = 4;
}
使用:
     int wall = direction.north;
看起來好像java版的更富有表達力,但事實并非如此。它不是類型安全的,你可能一不小心會把任何int型的值賦給wall而編譯器不會發出任何抱怨【譯注:你顯然不可以這么寫:direction wall = direction.north;】。坦白地說,在我的java編程經歷里,我從未因為該處非類型安全而花費太多的時間寫一些額外的東西來捕捉錯誤。但是,能擁有枚舉是一件快事。c#帶給你的一個驚喜是—當你調試程序時,如果你在使用枚舉變量的地方設置斷點,調試器將自動譯解direction并給你一個可讀的信息,而不是一個你自己不得不譯解的數值:
聲明:
public enum direction {north=1, east=2, west=4, south=8};
使用:
direction direction = direction.north | direction.west;
if ((direction & direction.north) != 0)
//....
如果你在if語句上設置斷點,你將得到一個你可讀的direction而不是數值5。
【譯注:這個例子改一下,會更有助于理解:
聲明:
public enum direction {north=1, east=2, west=4, south=8, middle = 5/*注意此處代碼*/};
使用:
direction direction = direction.north | direction.west;
if ((direction & direction.north) != 0)
//....
如果你在if語句上設置斷點,你將得到一個你可讀的direction(即middle)而不是數值5】
【作者注:枚舉被java拋棄的原因極有可能是因為它可以用類代替。正如我上面提到的,單單用類我們不能夠象用別的概念一樣更好地表達某個特性。java的“如果它可以用類處理,那就不引入一個新的結構”的哲學的優點何在?看起來最大的優點是簡單—較短的學習曲線,并且無需程序員去考慮做同一件事的多種方式。實際上,java語言在很多方面都以簡化為目標來改進c++,比如不用指針,不用頭文件,以及單根對象層次等。所有這些簡化的共性是它們實際上使得編程—唔—簡單了,可是,沒有我們剛才提到的枚舉、屬性和事件等等,反而使你的代碼更加復雜了】
7.集合和foreach語句
     c#提供一個for循環的捷徑,而且它還促進了集合類更為一致:
在java或c++中:
1. while (! collection.isempty())
{
    object o = collection.get();
    collection.next()
    //...
2. for (int i = 0; i < array.length; i++)
    //...
在 c#中:
1.  foreach (object o in collection)
    //...
2.  foreach (int i in array)
    //...
c#的for循環將工作于集合對象上(數組實現一個集合)。集合對象有一個getenumerator()方法,該方法返回一個enumerator對象。enumerator對象有一個movenext()方法和一個current屬性。
8.結構
     把c#的結構視為使語言的類型系統更為優雅而不僅是一種“如果你需要的話可以利用之寫出真正有效率的代碼”的概念更好些。
     在c++中,結構和類(對象)都可分配在棧或堆上。在c#中,結構永遠創建在棧上,類(對象)則永遠創建在堆上。使用結構實際上可以生成更有效率的代碼:
public struct vector
{
    public float direction;
    public int magnitude;
}
vector[] vectors = new vector [1000];
這將把1000個vector分配在一塊空間上,這比我們把vector聲明為類并使用for循環去實例化1000個獨立的vector來得有效率得多。【譯注:因懷疑原文有誤,此處故意漏譯一句,但不應影響你對這節內容的理解】:
int[] ints = new ints[1000];//【譯注:此處代碼有誤,應為int[] ints = new int[1000];】
c#完全允許你擴展內建在語言中的基本類型集。實際上,c#所有的基本類型都以結構方式實現的。int型只不過是system.int32結構的別名,long型不過是system.int64結構的別名等等。這些基本類型當然可被編譯器特別處理,但是語言本身并無區別【譯注:意思是語言自身對處理所有類型提供了一致的方法】。在下一節中,我們可看到c#是如何做到這一點的。
9.類型一致
     大多數語言都有基本類型(int、long等等)。高級類型最終是由基本類型構成的。能以同樣的方式處理基本類型和高級類型通常來說是有用處的。例如,如果集合可以象包容sting那樣包容int是有用的。為此,smalltalk通過犧牲些許效率象處理string或form一樣來處理int和long。java試圖避免這個效率損失,它象c和c++那樣處理基本類型,但又為每一個基本類型提供了相應的包裝類—int包裝為integer,double包裝為double。c++模板參數可接受任何類型,只要該類型提供了模板定義的操作的實現。
【譯注:在java中,你可以這么寫:
int i = 1;
      double d = 1.1;
      integer iobj = new integer(1);
double dobj = new double(1.1);
以下寫法是錯誤的:
int i = new int(1);
integer iobj = 1;

c#對該問題提供了一個不同的解決方案。在上一節里,我介紹了c#中的結構,指出基本類型不過是結構的一個別名而已。既然結構擁有所有對象類型擁有的方法,那代碼就可以這么寫:
int i = 5;
system.console.writeline (i.tostring());
如果我們想象使用一個對象那樣使用一個結構,c#將為你裝箱該結構為對象,當你再次需要使用結構時,可以通過拆箱實現:
stack stack = new stack ();
stack.push (i); // 裝箱
int j = (int) stack.pop(); //拆箱
拆箱不僅是類型轉換的需要,它也是一個無縫處理結構和類之間關系的方式。你要清楚裝箱是做了創建包裝類的工作,盡管clr可以為被裝箱的對象提供附加的優化。
【譯注:可以這么認為,在c#中,對于任何值(結構)類型,都存在如下的包裝類:
class t_box //t代表任何值類型
{
    t value;
    t_box(t t){value = t;}
}
當裝箱時,比如:
int n = 1;
object box = n;
概念上相當于:
int n = 1;
object box = new int_box(i);
當拆箱時,比如:
object box = 1;
int n = (int)box;
概念上相當于:
object box = new int_box(1);
int n = ((int_box)box).value;】
【作者注:c#的設計者在設計過程中應該考慮過模板。我懷疑未采用模板有兩個原因:第一個是混亂,模板可能很難和面向對象的特性融合在一起,它為程序員的帶來了太多的(混亂)設計可能性,而且它很難和反射一起工作;第二點是,如果.net庫(例如集合類)沒有使用模板的話,模板將不會太有用。不過,果真.net類使用了它們,那將有20多種使用.net類的語言不得不也要能和模板一起工作,這在技術上是非常難以實現的。
注意到模板(泛型)已經被java社團考慮納入java語言規范之中是一件有意思的事。或許每個公司都會各唱各的調—sun說“.net患了最小公分母綜合癥”,而微軟則說“java不支持多語言”。
(8月10日致歉)看了一個對anders hejlsberg的專訪后(http://windows.oreilly.com/news/hejlsberg_0800.html),感覺似乎模板已浮出地平線,但第一版沒有,正因我們上面提到的種種困難。看到il規范是如此寫法使得il碼可以展現模板(用一個非破壞的方式以讓反射可以很好的工作)而字節碼則不可以是一件很有趣的事。在此,我還給出了一個關于java社團考慮要加入泛型的鏈接:http://jcp.org/jsr/detail/014.jsp 】
【譯注:此處是上文提到的對anders hejlsberg采訪的中文版鏈接:http://www.csdn.net/develop/article/11/11580.shtm。另外,如欲了解更多關于泛型編程知識,請參見此處鏈接:http://www.csdn.net/develop/article/11/11440.shtm】
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 四子王旗| 马龙县| 扎鲁特旗| 鱼台县| 南通市| 墨脱县| 五指山市| 桂林市| 平舆县| 卓尼县| 定安县| 聂荣县| 宜宾市| 荥经县| 凤凰县| 玉山县| 繁昌县| 锦州市| 万安县| 涟源市| 邯郸市| 五莲县| 长宁区| 长葛市| 大埔县| 万盛区| 梅河口市| 贡山| 南投市| 恭城| 新竹市| 新源县| 黄山市| 宁波市| 尼勒克县| 资源县| 万州区| 福鼎市| 仲巴县| 昆明市| 岳阳市|