構造函數是和類名相同的類的一個方法,如果沒有顯式的聲明,在系統會在編譯的時候,自動生成一 個不帶參數的,不執行任何動作的構造函數。
但如果顯式的聲明了構造函數,系統就不會自動生成了。如果聲明的構造函數是有參數的構造函數, 我們在實例化類的時候,就必須以該構造函數而實例化類。看下面的代碼:
using System;
namespace gosoa.com.cn
{
public class test
{
public int num;
public test (int i)
{
this.num=i+5;
}
static void Main()
{
test classOne=new test(10);
int x=classOne.num;
Console.WriteLine(x);
}
}
}
如上代碼,在實例化類的時候,test classOne=new test(10); 傳遞了一個參數。如果我們test classOne=new test();這樣來實例化類,就會報錯了。因為我們顯式的聲明了一個帶參的構造方法,new test() 這樣實例化的時候,調用的是無參的構造函數,但類中卻沒有無參的構造函數。
我們再來看一下靜態構造函數。
在C# 中我們可以給類定義一個無參的靜態構造函數(注意,必須是無參的),只要創建類的對象,該 方法就會執行。該函數只執行一次,並且在代碼引用類之前執行。
一般,在類中有一些靜態字段或者屬性,需要在第一次使用類之前從外部數據源初始化這些靜態字段 和屬性,這時,我們就采用靜態構造函數的方式來解決。
靜態構造函數沒有訪問修飾符,其他C#代碼也不調用它,在加載類時,總是由.NET 運行庫調用它。一 個類只能有一個靜態構造函數。
注意,無參的實例構造函數可以和靜態構造函數在類中共存。因為靜態構造函數是在加載類的時候執 行的,而實例構造函數是在創建實例時執行的,兩者並不沖突。
我們看下面的例子
using System;
namespace gosoa.com.cn
{
public class test
{
static test()
{
Console.WriteLine("www.gosoa.com.cn");
}
public test ()
{
}
static void Main()
{
test classOne=new test();
}
}
}
該程序運行的結果是 www.gosoa.com.cn 在類的對象創建的時候,靜態構造函數已經運行了。
我們再來看一個例子
using System;
namespace gosoa.com.cn
{
public class test
{
private string domain;
private string url;
public test (string dom,string url)
{
this.domain=dom;
this.url=url;
}
public test(string dom)
{
this.domain=dom;
this.url="gosoa.com.cn";
}
static void Main()
{
test classOne=new test("gosoa");
Console.WriteLine(classOne.url);
}
}
}
在上例中,有兩個構造函數,有可能兩個構造函數需要初始化同一個字段,這種情況,C#中有個特殊 的語言,稱為“構造函數初始化器”可以實現。看下面代碼
using System;
namespace gosoa.com.cn
{
public class test
{
private string domain;
private string url;
public test (string dom,string url)
{
this.domain=dom;
this.url=url;
}
public test(string dom) : this (dom,"www.gosoa.com.cn")
{
}
static void Main()
{
test classOne=new test("gosoa");
Console.WriteLine(classOne.url);
}
}
}
如上實例,就是采用了 構造函數初始化器。注意,構造函數初始化器在構造函數之前執行。
2、只讀字段(readonly)。
只讀字段比常量靈活的多,常量(const)字段必須在聲明之初就初始化,但readonly字段甚至可以進行 一些運算再確定其值。
注意,可以在構造函數中對只讀字段賦值,但不能在其他地方賦值。