在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美

當前位置:雨林木風下載站 > 技術開發教程 > 詳細頁面

Top Ten Traps in C# for C++ Programmers中文版(轉)

Top Ten Traps in C# for C++ Programmers中文版(轉)

更新時間:2022-05-06 文章作者:未知 信息來源:網絡 閱讀次數:

【譯序:C#入門文章。請注意:所有程序調試環境為Microsoft Visual Studio.NET 7.0 Beta2和 Microsoft .NET Framework SDK Beta2。限于譯者時間和能力,文中倘有訛誤,當以英文原版為準】

在最近發表于《MSDN Magazine》(2001年7月刊)上的一篇文章里,我講了“從C++轉移到C#,你應該了解些什么?”。在那篇文章里,我說過C#和C++的語法很相似,轉移過程中的困難并非來自語言自身,而是對受管制的.NET環境的適應和對龐大的.NET框架的理解。

我已經編輯了一個C++和C#語法不同點的列表(可在我的WEB站點上找到這個列表。在站點上,點擊Books可以瀏覽《Programming C#》,也可以點擊FAQ看看)。正如你所意料的,很多語法上的改變是小而瑣細的。有一些改變對于粗心的C++程序員來說甚至是隱蔽的陷阱,本文將集中闡述十個危險的陷阱。

陷阱一.非確定性終結和C#析構器

理所當然,對于大多數C++程序員來說,C#中最大的不同是垃圾收集。這就意味你不必再擔心內存泄漏以及確保刪除指針對象的問題。當然,你也就失去了精確控制銷毀對象時機的能力。實際上,C#中并沒有顯式的析構器。

如果你在處理一個未受管制的資源,當你用完時,你需要顯式地釋放那些資源。可通過提供一個Finalize方法(稱為終結器)隱式控制資源,當對象被銷毀時,它將被垃圾收集器調用。

終結器只應該釋放對象攜帶的未受管制的資源,而且也不應該引用別的對象。注意:如果你只有一些受管制的對象引用那你用不著也不應該實現Finalize方法—它僅在需處理未受管制的資源時使用。因為使用終結器要付出代價,所以,你只應該在需要的方法上實現(也就是說,在使用代價昂貴的、未受管制的資源的方法上實現)。

永遠不要直接調用Finalize方法(除了在你自己類的Finalize里調用基類的Finalize方法外【譯注:此處說法似乎有誤,參見下面譯注!】),垃圾收集器會幫你調用它。

C#的析構器在句法上酷似C++的析構器,但它們本質不同。C#析構器僅僅是聲明Finalize方法并鏈鎖到其基類的一個捷徑【譯注:這句話的意思是,當一個對象被銷毀時,從最派生層次的最底層到最頂層,析構器將依次被調用,請參見后面給出的完整例子】。因此,以下寫法:

~MyClass()

{

//do work here

}

和如下寫法具有同樣效果:

MyClass.Finalize()

{

// do work here

base.Finalize();//

}

【譯注:上面這段代碼顯然是錯誤的,首先應該寫為:

class MyClass

{

void Finalize()

{

// do work here

base.Finalize();//這樣也不可以!編譯器會告訴你不能直接調用基類的Finalize方法,它將從析構函數中自動調用。關于原因,請參見本小節后面的例子和陷阱二的有關譯注!

}

}

下面給出一個完整的例子:

using System;

class RyTestParCls

{

~RyTestParCls()

{

Console.WriteLine("RyTestParCls's Destructor");

}

}

class RyTestChldCls: RyTestParCls

{

~RyTestChldCls()

{

Console.WriteLine("RyTestChldCls's Destructor");

}

}

public class RyTestDstrcApp

{

public static void Main()

{

RyTestChldCls rtcc = new RyTestChldCls();

rtcc = null;

GC.Collect();//強制垃圾收集

GC.WaitForPendingFinalizers();//掛起當前線程,直至處理終結器隊列的線程清空該隊列

Console.WriteLine("GC Completed!");

}

}

以上程序輸出結果為:

RyTestChldCls's Destructor

RyTestParCls's Destructor

GC Completed!

注意:在CLR中,是通過重載System.Object的虛方法Finalize()來實現虛方法的,在C#中,不允許重載該方法或直接調用它,如下寫法是錯誤的:

class RyTestFinalClass

{

override protected void Finalize() {}//錯誤!不可重載System.Object方法。

}

同樣,如下寫法也是錯誤的:

class RyTestFinalClass

{

public void SelfFinalize() //注意!這個名字是自己取的,不是Finalize

{

this.Finalize()//錯誤!不能直接調用Finalize()

base.Finalize()//錯誤!不能直接調用基類Finalize()

}

}

class RyTestFinalClass

{

protected void Finalize() //注意!這個名字和上面不一樣,同時,它也不是override的,這是可以的,這樣,你就隱藏了基類的Finalize。

{

this.Finalize()//自己調自己,當然可以,但這是個遞歸調用你想要的嗎?J

base.Finalize()//錯誤!不能直接調用基類Finalize()

}

}

對這個主題的完整理解請參照陷阱二。】

陷阱二.Finalize和Dispose

顯式調用終結器是非法的,Finalize方法應該由垃圾收集器調用。如果是處理有限的、未受管制的資源(比如文件句柄),你或許想盡可能快地關閉和釋放它,那你應該實現IDisposable接口。這個接口有一個Dispose方法,由它執行清除動作。類的客戶負責顯式調用該Dispose方法。Dispose方法允許類的客戶說“不要等Finalize了,現在就干吧!”。

如果提供了Dispose方法,你應該禁止垃圾收集器調用對象的Finalize方法—既然要顯式進行清除了。為了做到這一點,應該調用靜態方法GC.SuppressFinalize,并傳入對象的this指針,你的Finalize方法就能夠調用Dispose方法。

你可能會這么寫:

public void Dispose()

{

// 執行清除動作

// 告訴垃圾收集器不要調用Finalize

GC.SuppressFinalize(this);

}

public override void Finalize()

{

Dispose();

base.Finalize();

}

【譯注:以上這段代碼是有問題的,請參照我在陷阱一中給的例子。微軟站點上有一篇很不錯的文章(Gozer the Destructor),說法和這兒基本一致,但其代碼示例在Microsoft Visual Studio.NET 7.0 Beta2和 Microsoft .NET Framework SDK Beta2都過不了,由于手頭沒有Beta1比對,所以,現在還不能確定是文章的筆誤,還是因為Beta1和Beta2的不同而導致,還是我沒有準確地理解這個問題。比如下面這個例子(來自Gozer the Destructor)在Beta2環境下無法通過:

class X

{

public X(int n)

{

this.n = n;

}

~X()

{

System.Console.WriteLine("~X() {0}", n);

}

public void Dispose()

{

Finalize();//此行代碼在Beta2環境中出錯!編譯器提示,不能調用Finalize,可考慮調用Idisposable.Dispose(如可用)

System.GC.SuppressFinalize(this);

}

private int n;

};

class main

{

static void f()

{

X x1 = new X(1);

X x2 = new X(2);

x1.Dispose();

}

static void Main()

{

f();

System.GC.Collect();

System.GC.WaitForPendingFinalizers();

}

};

而該文聲稱會有如下輸出:

~X() 1

~X() 2

why?】

對于某些對象來說,你可能寧愿讓你的客戶調用Close方法(例如,對于文件對象來說,Close比Dispose更妥貼)。那你可以通過創建一個private的Dispose方法和一個public的Close方法,并且在Close里調用Dispose。

因為你并不能肯定客戶將調用Dispose,并且終結器是不確定的(你無法控制什么時候運行GC),C#提供了using語句以確保盡可能早地調用Dispose。這個語句用于聲明你正在使用什么對象,并且用花括號為這些對象創建一個作用域。當到達“}”J時,對象的Dispose方法將被自動調用:

using System.Drawing;

class Tester

{

public static void Main()

{

using (Font theFont = new Font("Arial", 10.0f))

{

// 使用theFont

} // 編譯器為theFont調用Dispose

Font anotherFont = new Font("Courier",12.0f);

using (anotherFont)

{

// 使用 anotherFont

} // 編譯器為anotherFont調用Dispose

}

}

在上例的第一部份,theFont對象在using語句內創建。當using語句的作用域結束,theFont對象的Dispose方法被調用。例子第二部份,在using語句外創建了一個anotherFont對象,當你決定使用anotherFont對象時,可將其放在using語句內,當到達using語句的作用域尾部時,對象的Dispose方法同樣被調用。

using 語句還可保護你處理未曾意料的異常,不管控制是如何離開using語句的,Dispose都會被調用,就好像那兒有個隱式的try-catch-finally程序塊。

陷阱三.C#區分值類型和引用類型

和C++一樣,C#是一個強類型語言。并且象C++一樣,C#把類型劃分為兩類:語言提供的固有(內建)類型和程序員定義的用戶自定義類型【譯注:即所謂的UDT】。

除了區分固有類型和用戶自定義類型外,C#還區分值類型和引用類型。就象C++里的變量一樣,值類型在棧上保存值(除了嵌在對象中的值類型)。引用類型變量本身位于棧上,但它們所指向的對象則位于堆上,這很象C++里的指針【譯注:這其實更象C++里的引用J】。當被傳遞給方法時,值類型是傳值(做了一個拷貝)而引用類型則按引用高效傳遞。

類和接口創建引用類型【譯注:這個說法有點含糊,不能直接創建接口類型的對象,也并不是每一種類類型都是可以的,但可以將它們派生類的實例的引用賦給它們(說到“類類型”,不由得想起關于“型別”一詞的風風雨雨J)】,但要謹記(參見陷阱五):和所有固有類型一樣,結構也是值類型。

【譯注:可參見陷阱五的例子】

陷阱四.警惕隱式裝箱

裝箱和拆箱是使值類型(如整型等)能夠象引用類型一樣被處理的過程。值被裝箱進一個對象,隨后的拆箱則是將其還原為值類型。C#里的每一種類型包括固有類型都是從object派生下來并可以被隱式轉換為object。對一個值進行裝箱相當于創建一個對象,并將該值拷貝入該對象。

裝箱是隱式進行的,因此,當需要一個引用類型而你提供的是值類型時,該值將會被隱式裝箱。裝箱帶來了一些執行負擔,因此,要盡可能地避免裝箱,特別是在一個大的集合里。

如果要把被裝箱的對象轉換回值類型,必須將其顯式拆箱。拆箱動作分為兩步:首先檢查對象實例以確保它是一個將被轉換的值類型的裝箱對象,如果是,則將值從該實例拷貝入目標值類型變量。若想成功拆箱,被拆箱的對象必須是目標值類型的裝箱對象引用。

using System;

public class UnboxingTest

{

public static void Main()

{

int i = 123;

//裝箱

object o = i;

// 拆箱 (必須顯式進行)

int j = (int) o;

Console.WriteLine("j: {0}", j);

}

}

如果被拆箱的對象為null或是一個不同于目標類型的裝箱對象引用,那將拋出一個InvalidCastException異常。【譯注:此處說法有誤,如果正被拆箱的對象為null,將拋出一個System.NullReferenceException而不是System.InvalidCastExcepiton】

【譯注:關于這個問題,我在另一篇譯文(A Comparative Overview of C#中文版(上篇))里有更精彩的描述J】

陷阱五.C#中結構是大不相同的

C++中的結構幾乎和類差不多。在C++中,唯一的區別是結構【譯注:指成員】缺省來說具有public訪問(而不是private)級別并且繼承缺省也是public(同樣,不是private)的。有些C++程序員把結構當成只有數據成員的對象,但這并不是語言本身支持的約定,而且這種做法也是很多OO設計者所不鼓勵的。

在C#中,結構是一個簡單的用戶自定義類型,一個非常不同于類的輕量級替代品。盡管結構支持屬性、方法、字段和操作符,但結構并不支持繼承或析構器之類的東西。

更重要的是,類是引用類型,而結構是值類型(參見陷阱三)。因此,結構對表現不需要引用語義的對象就非常有用。在數組中使用結構,在內存上會更有效率些,但若在集合里,就不是那么有效率了—集合需要引用類型,因此,若在集合中使用結構,它就必須被裝箱(參見陷阱四),而裝箱和拆箱需要額外的負擔,因此,在大的集合里,類可能會更有效。

【譯注:下面是一個完整的例子,它同時還演示了隱式類型轉換,請觀察一下程序及其運行結果J

using System;

class RyTestCls

{

public RyTestCls(int AInt)

{

this.IntField = AInt;

}

public static implicit operator RyTestCls(RyTestStt rts)

{

return new RyTestCls(rts.IntField);

}

private int IntField;

public int IntProperty

{

get

{

return this.IntField;

}

set

{

this.IntField = value;

}

}

}

struct RyTestStt

{

public RyTestStt(int AInt)

{

this.IntField = AInt;

}

public int IntField;

}

class RyClsSttTestApp

{

public static void ProcessCls(RyTestCls rtc)

{

rtc.IntProperty = 100;

}

public static void ProcessStt(RyTestStt rts)

{

rts.IntField = 100;

}

public static void Main()

{

RyTestCls rtc = new RyTestCls(0);

rtc.IntProperty = 200;

ProcessCls(rtc);

Console.WriteLine("rtc.IntProperty = {0}", rtc.IntProperty);

RyTestStt rts = new RyTestStt(0);

rts.IntField = 200;

ProcessStt(rts);

Console.WriteLine("rts.IntField = {0}", rts.IntField);

RyTestStt rts2= new RyTestStt(0);

rts2.IntField = 200;

ProcessCls(rts2);

Console.WriteLine("rts2.IntField = {0}", rts2.IntField);

}

}

以上程序運行結果為:

rtc.IntProperty = 100

rtc.IntField = 200

rts2.IntField = 200

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

在线看毛片视频-国产免费av在线-欧美日韩一区二区三区-国产成人无码av在线播放无广告-亚洲人va欧美va人人爽-国产第一草草-西班牙黄色片-四虎在线网站8848-最新av片免费网站入口-东京热无码中文字幕av专区-日本大人吃奶视频xxxx-欧美精品一区二区三区四区五区-国产片天天弄-国产免费内射又粗又爽密桃视频-欧美爱爱网站-日韩v欧美
  • <li id="86scu"><menu id="86scu"></menu></li>
    <li id="86scu"></li>
    <button id="86scu"></button>
  • <s id="86scu"></s><button id="86scu"><menu id="86scu"></menu></button>
  • 又粗又黑又大的吊av| 性欧美1819| 无码人妻精品一区二区蜜桃百度| 91亚洲免费视频| 亚洲综合婷婷久久| 亚洲狼人综合干| 奇米影视四色在线| 波多野结衣国产精品| 日本黄色的视频| 99re99热| 日本a视频在线观看| 国内外成人免费激情视频| 免费在线观看毛片网站| 北条麻妃在线视频| 亚洲免费av一区| 超碰在线免费观看97| 国产日产欧美一区二区| 妞干网在线视频观看| 亚洲乱码中文字幕久久孕妇黑人| 成人3d动漫一区二区三区| 手机免费看av网站| av中文字幕av| 成人午夜视频免费在线观看| 色一情一区二区| 99久久99久久精品| 国产在线青青草| 亚洲视频在线不卡| 亚洲精品无码久久久久久| 91 视频免费观看| 日韩极品视频在线观看| 国产野外作爱视频播放| 久久久天堂国产精品| 一区二区三区国产免费| 久草视频这里只有精品| 伊人色在线观看| 欧美韩国日本在线| 五月天在线免费视频| 黄色高清无遮挡| 日本阿v视频在线观看| 激情五月亚洲色图| 日韩人妻无码精品久久久不卡| 欧美国产日韩在线播放| 日韩黄色短视频| 亚洲 欧洲 日韩| 污视频在线观看免费网站| 欧美做受777cos| 37pao成人国产永久免费视频| 欧美一级黄色录像片| 亚洲欧美在线精品| 欧美成人免费高清视频| 少妇高潮喷水在线观看| 国产精品12p| 国产乱码一区二区三区四区| 日本va中文字幕| 日本一道本久久| 国产视频在线观看网站| 久久最新免费视频| 性久久久久久久久久久久久久| 亚洲激情在线观看视频| 国产情侣av自拍| 日日碰狠狠丁香久燥| 国产精品自拍片| 水蜜桃色314在线观看| 51xx午夜影福利| 国产一二三四区在线观看| 国产麻豆电影在线观看| 五月天六月丁香| 中文字幕一区二区三区四区五区人| 日韩av.com| 在线无限看免费粉色视频| 日本免费在线视频观看| 中文字幕の友人北条麻妃| 50度灰在线观看| 国产伦精品一区二区三区四区视频_| 国产成人亚洲综合无码| 亚洲黄色网址在线观看| 国产毛片久久久久久国产毛片| 国产一线二线三线女| 女性女同性aⅴ免费观女性恋| 久久成人免费观看| 欧美日韩亚洲一二三| www.se五月| 天天做天天爱天天高潮| 97超碰人人澡| 国产av人人夜夜澡人人爽| 性生生活大片免费看视频| 91看片淫黄大片91| 国产青青在线视频| 日本中文字幕观看| 国产一区二区三区小说| 欧美婷婷精品激情| 欧美 日韩 国产精品| 久久美女福利视频| 国产又粗又猛大又黄又爽| 成人在线视频一区二区三区| 欧美日韩大尺度| 亚洲欧美日韩不卡| 日韩欧美精品在线观看视频| 亚洲美女性囗交| 免费成人午夜视频| 日韩va在线观看| 日本三级免费观看| 波多野结衣与黑人| 九九九九九国产| 青青青在线播放| 国产www免费| 91麻豆天美传媒在线| 国产日韩成人内射视频| 91免费国产精品| 不卡的在线视频| 日本888xxxx| 国产免费观看高清视频| 日韩人妻一区二区三区蜜桃视频| 日韩精品无码一区二区三区免费 | 日韩欧美视频免费在线观看| 成人精品视频一区二区| 日本手机在线视频| 青青草综合视频| 999热精品视频| 一区二区三区欧美精品| 能在线观看的av网站| 精品欧美一区免费观看α√| 996这里只有精品| 最新av网址在线观看| 伊人免费视频二| 国产精欧美一区二区三区白种人| 国产成人综合一区| 日本一区二区黄色| 亚洲中文字幕无码专区| 波多野结衣综合网| 男女激情无遮挡| 国产97在线 | 亚洲| 国产乱淫av片杨贵妃| 大荫蒂性生交片| 久久国产精品视频在线观看| 久久久亚洲国产精品| 国产高清www| 日本福利视频在线| 国产女女做受ⅹxx高潮| 日韩一级片播放| 中文字幕日韩综合| 免费成人进口网站| 黄网站色视频免费观看| 精品少妇人妻av免费久久洗澡| 波多野结衣之无限发射| 国产成人在线免费看| 18岁视频在线观看| 午夜剧场在线免费观看| 99精品视频免费版的特色功能| 亚洲五月激情网| 欧美国产综合在线| 鲁一鲁一鲁一鲁一澡| 亚洲一区在线不卡| 黄黄视频在线观看| 久久久性生活视频| 麻豆三级在线观看| 欧美日韩dvd| 50路60路老熟妇啪啪| 亚洲三级在线观看视频| 九九爱精品视频| 亚洲图片 自拍偷拍| av 日韩 人妻 黑人 综合 无码| 日韩欧美国产综合在线| 午夜免费高清视频| 国产爆乳无码一区二区麻豆| 欧美aⅴ在线观看| 99热这里只有精品7| aa免费在线观看| 精品免费久久久久久久| 亚洲最大成人在线观看| 日韩国产一级片| 99亚洲精品视频| 欧美 日韩 国产 激情| www插插插无码免费视频网站| 欧美性猛交xxx乱久交| 丰满少妇大力进入| √天堂资源在线| 亚洲综合色在线观看| 99久久国产综合精品五月天喷水| 午夜免费看毛片| 北条麻妃在线观看| 亚洲色成人www永久在线观看| www.久久91| 手机在线免费观看毛片| 熟女少妇在线视频播放| 日韩精品一区二区在线视频 | 欧美午夜aaaaaa免费视频| 国产 日韩 欧美在线| 97精品国产97久久久久久粉红 | 中文字幕第50页| 潘金莲激情呻吟欲求不满视频| 国语对白做受xxxxx在线中国| 国产一级片91| 日韩人妻一区二区三区蜜桃视频| 亚洲欧美日韩综合网| 久热精品在线观看视频| 欧美精品性生活| 91欧美视频在线| 国产精品区在线| 亚洲一级片免费观看|