程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> C#銳利體驗(七)

C#銳利體驗(七)

編輯:C#基礎知識

  第七講 域與屬性

  域

  域(Field)又稱成員變量(Member Variable),它表示存儲位置,是C#中類不可缺少的一部分。域的類型可以是C#中任何數據類型。但對於除去string類型的其他引用類型由於在初始化時涉及到一些類的構造器的操作,我們這裡將不提及,我們把這一部分內容作為“類的嵌套”放在“接口 繼承與多態”一講內來闡述。

  域分為實例域和靜態域。實例域屬於具體的對象,為特定的對象所專有。靜態域屬於類,為所有對象所共用。C#嚴格規定實例域只能通過對象來獲取,靜態域只能通過類來獲取。例如我們有一個類型為MyClass的對象MyObject,MyClass內的實例域instanceField(存取限制為public)只能這樣獲取:MyObject. instanceField。而MyClass的靜態域staticField(存取限制為public)只能這樣獲取:MyClass.staticField。注意靜態域不能像傳統C++那樣通過對象獲取,也就是說MyObject.staticField的用法是錯誤的,不能通過編譯器編譯。

  域的存取限制集中體現了面向對象編程的封裝原則。如前所述,C#中的存取限制修飾符有5種,這5種對域都適用。C#只是用internal擴展了C++原來的friend修飾符。在有必要使兩個類的某些域互相可見時,我們將這些類的域聲明為internal,然後將它們放在一個組合體內編譯即可。如果需要對它們的繼承子類也可見的話,聲明為protected internal即可。實際上這也是組合體的本來意思--將邏輯相關的類組合封裝在一起。

  C#引入了readonly修飾符來表示只讀域,const來表示不變常量。顧名思義對只讀域不能進行寫操作,不變常量不能被修改,這兩者到底有什麼區別呢?只讀域只能在初始化--聲明初始化或構造器初始化--的過程中賦值,其他地方不能進行對只讀域的賦值操作,否則編譯器會報錯。只讀域可以是實例域也可以是靜態域。只讀域的類型可以是C#語言的任何類型。但const修飾的常量必須在聲明的同時賦值,而且要求編譯器能夠在編譯時期計算出這個確定的值。const修飾的常量為靜態變量,不能夠為對象所獲取。const修飾的值的類型也有限制,它只能為下列類型之一(或能夠轉換為下列類型的):sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, enum類型, 或引用類型。值得注意的是這裡的引用類型,由於除去string類型外,所有的類型出去null值以外在編譯時期都不能由編譯器計算出他們的確切的值,所以我們能夠聲明為const的引用類型只能為string或值為null的其他引用類型。顯然當我們聲明一個null的常量時,我們已經失去了聲明的意義--這也可以說是C#設計的尴尬之處!

  這就是說,當我們需要一個const的常量時,但它的類型又限制了它不能在編譯時期被計算出確定的值來,我們可采取將之聲明為static readonly來解決。但兩者之間還是有一點細微的差別的。看下面的兩個不同的文件:

//file1.cs
//csc /t:library file1.cs
using System;
namespace MyNamespace1
{
public class MyClass1
{
        public static readonly int myField = 10;
    }
}
//file2.cs
//csc /r:file1.dll file2.cs
using System;
namespace MyNamespace2
{
public class MyClass1
{
        public static void Main()
        {
Console.WriteLine(MyNamespace1.MyClass1.myField);
        }
    }
}

  我們的兩個類分屬於兩個文件file1.cs 和file2.cs,並分開編譯。在文件file1.cs內的域myField聲明為static readonly時,如果我們由於某種需要改變了myField的值為20,我們只需重新編譯文件file1.cs為file1.dll,在執行file2.exe時我們會得到20。但如果我們將static readonly改變為const後,再改變myField的初始化值時,我們必須重新編譯所有引用到file1.dll的文件,否則我們引用的MyNamespace1.MyClass1.myField將不會如我們所願而改變。這在大的系統開發過程中尤其需要注意。實際上,如果我們能夠理解const修飾的常量是在編譯時便被計算出確定的值,並代換到引用該常量的每一個地方,而readonly時在運行時才確定的量--只是在初始化後我們不希望它的值再改變,我們便能理解C#設計者們的良苦用心,我們才能徹底把握const和readonly的行為!

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