程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#中結構函數和析構函數用法實例詳解

C#中結構函數和析構函數用法實例詳解

編輯:C#入門知識

C#中結構函數和析構函數用法實例詳解。本站提示廣大學習愛好者:(C#中結構函數和析構函數用法實例詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是C#中結構函數和析構函數用法實例詳解正文


本文實例講述了C#中結構函數和析構函數用法。分享給年夜家供年夜家參考,詳細以下:

結構函數與析構函數是一個類中看似較為簡略的兩類函數,但在現實應用進程中總會湧現一些意想不到的運轉毛病。本文將較體系的引見結構函數與析構函數的道理及在C#中的應用,和在應用進程中須要留意的若干事項。

一.結構函數與析構函數的道理

作為比C更先輩的說話,C#供給了更好的機制來加強法式的平安性。C#編譯用具有嚴厲的類型平安檢討功效,它簡直能找出法式中一切的語法成績,這切實其實幫了法式員的年夜忙。然則法式經由過程了編譯檢討其實不表現毛病曾經不存在了,在“毛病”的年夜家庭裡,“語法毛病”的位置只能算是冰山一角。級別高的毛病平日隱蔽得很深,不輕易發明。

依據經歷,很多難以發覺的法式毛病是因為變量沒有被准確初始化或消除形成的,而初始化和消除任務很輕易被人遺忘。微軟應用面向對象的概念在設計C#說話時充足斟酌了這個成績並很好地予以處理:把對象的初始化任務放在結構函數中,把消除任務放在析構函數中。當對象被創立時,結構函數被主動履行。當對象滅亡時,析構函數被主動履行。如許就不消擔憂忘卻對象的初始化和消除任務。

二.結構函數在C#中的應用

結構函數的名字不克不及隨意起,必需讓編譯器認得出才可以被主動履行。它的定名辦法既簡略又公道:讓結構函數與類同名。除名字外,結構函數的另外一個特殊的地方是沒有前往值類型,這與前往值類型為void的函數分歧。假如它有前往值類型,那末編譯器將手足無措。在你可以拜訪一個類的辦法、屬性或任何其它器械之前,第一條履行的語句是包括有響應類的結構函數。乃至你本身不寫一個結構函數,也會有一個缺省結構函數供給給你。

上面羅列了幾品種型的結構函數

1)缺省結構函數

class TestClass
{
  public TestClass(): base() {}
}

下面已引見,它由體系(CLR)供給。

2)實例結構函數

實例結構函數是完成對類中實例停止初始化的辦法成員。如:

using System;
class Point
{
public double x, y;
public Point()
{
this.x = 0;
this.y = 0;
}
public Point(double x, double y)
{
this.x = x;
this.y = y;
}
…
}
class Test
{
static void Main()
{
Point a = new Point();
Point b = new Point(3, 4); // 用結構函數初始化對象
…
}
}

聲清楚明了一個類Point,它供給了兩個結構函數。它們是重載的。一個是沒有參數的Point結構函數和一個是有兩個double參數的Point結構函數。假如類中沒有供給這些結構函數,那末會CLR會主動供給一個缺省結構函數的。但一旦類中供給了自界說的結構函數,如Point()和Point (double x, double y),則缺省結構函數將不會被供給,這一點要留意。

3) 靜態結構函數

靜態結構函數是完成對一個類停止初始化的辦法成員。它普通用於對靜態數據的初始化。靜態結構函數不克不及有參數,不克不及有潤飾符並且不克不及被挪用,當類被加載時,類的靜態結構函數主動被挪用。如:

using System.Data;
class Employee
{
private static DataSet ds;
static Employee()
{
ds = new DataSet(...);
}
...
}

聲清楚明了一個有靜態結構函數的類Employee。留意靜態結構函數只能對靜態數據成員停止初始化,而不克不及對非靜態數據成員停止初始化。然則,非靜態結構函數既可以對靜態數據成員賦值,也能夠對非靜態數據成員停止初始化。

假如類僅包括靜態成員,你可以創立一個private的結構函數:private TestClass() {…},然則private意味著從類的裡面弗成能拜訪該結構函數。所以,它不克不及被挪用,且沒有對象可以被該類界說實例化。

以上是幾品種型結構函數的簡略應用,上面將重點引見一下在類的條理構造中(即繼續構造中)基類和派生類的結構函數的應用方法。派生類對象的初始化由基類和派生類配合完成:基類的成員由基類的結構函數初始化,派生類的成員由派生類的結構函數初始化。

當創立派生類的對象時,體系將會挪用基類的結構函數和派生類的結構函數,結構函數的履行順序是:先履行基類的結構函數,再履行派生類的結構函數。假如派生類又有對象成員,則,先履行基類的結構函數,再履行成員對象類的結構函數,最初履行派生類的結構函數。

至於履行基類的甚麼結構函數,缺省情形下是履行基類的無參結構函數,假如要履行基類的有參結構函數,則必需在派生類結構函數的成員初始化表中指出。如:

class A
{
private int x;
public A( ) { x = 0; }
public A( int i ) { x = i; }
}
class B : A
{
private int y;
public B( ) { y = 0; }
public B( int i ) { y = i; }
public B( int i, int j ):A(i) { y = j; }
}
B b1 = new B(); //履行基類A的結構函數A(),再履行派生類的結構函數B()
B b2 = new B(1); //履行基類A的結構函數A(),再履行派生類的結構函數B(int)
B b3 = new B(0,1); //履行履行基類A的結構函數A(int) ,再履行派生類的結構函數B(int,int)

在這裡結構函數的履行順序是必定要剖析清晰的。別的,假如基類A中沒有供給無參結構函數public A( ) { x = 0; },則在派生類的一切結構函數成員初始化表中必需指出基類A的有參結構函數A(i),以下所示:

class A
{
private int x;
public A( int i ) { x = i; }
}
class B : A
{
private int y;
public B():A(i) { y = 0; }
public B(int i):A(i) { y = i; }
public B(int i, int j):A(i) { y = j; }
}

三.析構函數和渣滓收受接管器在C#中的應用

析構函數是完成燒毀一個類的實例的辦法成員。析構函數不克不及有參數,不克不及有任何潤飾符並且不克不及被挪用(是體系主動挪用)。因為析構函數的目標與結構函數的相反,就加前綴‘~'以示差別。

固然C#(更確實的說是CLR)供給了一種新的內存治理機制---主動內存治理機制(Automatic memory management),資本的釋放是可以經由過程“渣滓收受接管器” 主動完成的,普通不須要用戶干涉,但在有些特別情形下照樣須要用到析構函數的,如在C#中非托管資本的釋放。

資本的釋放普通是經由過程"渣滓收受接管器"主動完成的,但詳細來講,仍有些須要留意的處所:

1. 值類型和援用類型的援用實際上是不須要甚麼"渣滓收受接管器"來釋放內存的,由於當它們出了感化域後會主動釋放所占內存,由於它們都保留在棧(Stack)中;

2. 只要援用類型的援用所指向的對象實例才保留在堆(Heap)中,而堆由於是一個自在存儲空間,所以它並沒有像"棧"那樣有生計期("棧"的元素彈出後就代表生計期停止,也就代表釋放了內存),而且要留意的是,"渣滓收受接管器"只對這塊區域起感化;

但是,有些情形下,當須要釋放非托管資本時,就必需經由過程寫代碼的方法來處理。平日是應用析構函數釋放非托管資本,將用戶本身編寫的釋放非托管資本的代碼段放在析構函數中便可。須要留意的是,假如一個類中沒有應用到非托管資本,那末必定不要界說析構函數,這是由於對象履行了析構函數,那末"渣滓收受接管器"在釋放托管資本之前要先挪用析構函數,然後第二次才真正釋放托管資本,如許一來,兩次刪除舉措的花消比一次年夜多的。上面應用一段代碼來示析構函數是若何應用的:

public class ResourceHolder
{
…
~ResourceHolder()
{
// 這裡是清算非托管資本的用戶代碼段
}
}

四.小結

結構函數與析構函數固然是一個類中情勢上較簡略的函數,但它們的應用決非看上去那末簡略,是以靈巧而准確的應用結構函數與析構函數可以或許幫你更好的懂得CLR的內存治理機制,和更好的治理體系中的資本。

注:CLR

CLR(公共說話運轉庫)和Java虛擬機一樣也是一個運轉時情況,它擔任資本治理(內存分派和渣滓搜集),並包管運用和底層操作體系之間需要的分別。

為了進步平台的靠得住性,和為了到達面向事務的電子商務運用所請求的穩固性級別,CLR還要擔任其他一些義務,好比監督法式的運轉。依照.NET的說法,在CLR監督之下運轉的法式屬於“受治理的”(managed)代碼,而不在CLR之下、直接在裸機上運轉的運用或許組件屬於“非受治理的” (unmanaged)的代碼。

CLR將監督五花八門的罕見編程毛病,很多年來這些毛病一向是軟件毛病的重要本源,個中包含:拜訪數組元素越界,拜訪未分派的內存空間,因為數據體積過年夜而招致的內存溢出,等等。

願望本文所述對年夜家C#法式設計有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved