C#---數據類型


     C#中的類型一共分為兩大類型:值類型和引用類型。

     值類型包括:簡單類型,結構類型和枚舉類型,其中簡單類型又包括:整數類型,實數類型(double,float,decimal),布爾類型(bool),字符類型。這里比較陌生的就是decimal,它表示小數,使用的時候必須在數字后面添加后綴:M(float同理,添加F),否則會被當做double處理。

     結構類型就是我們以前的結構體,定義的方式也是一樣的:

public struct Student{
     public String name;
     public int number;
};

     訪問結構類型的成員像是這樣:Student.name。
     結構類型可以有變量(但是不能初始化),也可以有方法,就像類一樣,但是不能被繼承。使用結構類型的原因就是它是值類型,如果僅僅是一些數據的話,可以放在結構類型中,這樣開銷會比較小,但如果需要添加方法,就得使用類。

    枚舉類型也是好用的類型,我們可以這樣定義一個枚舉:

enum City{
    SHANGHAI, BEIJING
};

     因為枚舉已經變成了類型(事實上,java的枚舉也是一個類),所以我們可以進行類型轉換,像是這樣:

City city = City.SHANGHAI;
int number = (int)city;
City city2 = (City)number;

     學過java的人都知道,枚舉中都是字面常量,我們可以像使用靜態字段一樣直接使用。C#中的枚舉和java的枚舉使用方法都是一樣,但是,C#可以實現類型轉換,這點倒是令我感到驚訝。
     引用類型包括:字符串類型,數組類型,類類型,接口類型,委托類型和對象類型。

     字符串類型和其他語言是一樣的,先講講字符串的比較,因為我們經常用到。

     在java中,習慣使用equals(),不使用==的原因就是它默認是比較引用,但java不能重載運算符。C#中比較的原理是根據字符串中每個字符的編碼值(C#使用Unicode編碼)。比較的方法很多,但我還是用回我習慣的Equals()好了。

     C#中的字符串還有一個非常好用的特性:對於字符串需要進行轉義的字符,我們可以直接在該字符串前面添加@字符,就不需要使用反斜杠,像是這樣:

String s = @"c:\..";

      以前的話,我們就得這樣使用:

String s = "c:\\..";

     如果需要轉義的字符夠多,簡直就是惡夢!

     字符串類型還有一個問題:與其他類型的轉化。如果是java,我想把一個字符串轉化為相應的int,我會使用Integer.parseInt(),在C#中,我們可以這樣使用:

int number = Int32.Parse("123");
String str = Convert.ToString(number);

      數組類型作為引用類型並不奇怪,java中的數組除了存儲基本類型的數組之外,其他都是當做引用數組,但C#不存在基本類型的說法,它們所有的類型都是System.Object,即對象類型。

      類類型和接口類型和java差不多,但接口類型不能包含字段,所謂的字段,其實就是初始化的變量,像是int i = 12是不允許的,而且,類的成員變量使用前綴_,而接口類型的變量前綴為I。

      重點是委托類型。這是一個神奇的類型,它的作用類似設計模式中常說的委托類。
      我們來看看一個簡單的委托類型的使用:

 public delegate double PriceDelegate();
    class Price
    {
        public double _Price;
        public void SetPrice(double price)
        {
            this._Price = price;
        }
        public double GetPrice()
        {
            return this._Price;
        }
        public double GetDiscountPrice()
        {
            return this._Price * 0.9;
        }
    }

           接着我們來做一個測試:

      public static void Main(String[] args){
            Price price = new Price();
            price.SetPrice(10);
            PriceDelegate delegatePrice = new PriceDelegate(price.GetPrice);
            Console.WriteLine(delegatePrice());
            delegatePrice = new PriceDelegate(price.GetDiscountPrice);
            Console.WriteLine(delegatePrice());
      }

     我們可以看到,策略模式在這里已經被內置了!我們可以利用委托類型簡單的實現策略模式(它到底算不算是策略模式還是個問題,因為策略模式是將算法交給具體實現,但顯然我們一開始就已經在類中實現了,以后如果想要替換算法,我們就必須到類的實現中修改,當然,使用繼承就可以解決這個問題,在派生類中添加新的算法)。
     更加嚴謹的說法應該是充分使用了回調,我們定義好一個方法,然后在需要的時候進行調用。委托類型是有局限的,它規定,作為參數的方法的返回值和參數列表必須和委托類型一樣。基於這點,委托類型更接近函數指針,但顯然比它好用多了(學習C++的時候,指針的使用一直是我最大的痛苦!)。我們可以想象,在委托類型的運作中,調用作為參數的方法,然后將調用結果返回。委托類型讓我想到了javascript,這說明,C#比起java,面向對象的程度更高。

     說到類型,繞不開的話題就是類型轉換,尤其是基本類型轉換為引用類型。

     java中是利用包裝類實現基本類型的包裝,但是,C#是利用裝箱和拆箱機制。

    C#中所有類型都可以向上轉型為System.Object,所以,我們將類型轉化為Object,這就是裝箱(很形象的說法,java是每個基本類型都有一個包裝類,就像每種糖果都有自己特有的包裝一樣,但是,C#直接利用一個Object將所有的東西裝起來,不就像一個箱子?),接着再強制轉換為我們需要的類型。

    我們注意到,其實java的包裝機制和C#的裝箱機制完全不一樣,適用的范圍根本不一樣,包裝機制是將基本類型轉化為對應的包裝類,裝箱機制是將所有值類型轉化為Object。

     講到類型轉換,C#總是讓我大開眼界,像是專門用於轉型的is和as操作符,就讓我會心一笑。

     我們可以使用is操作符來檢查一個對象是否兼容於指定的類型,並返回一個Boolean值。

     public static void Main(String[] args)
        {
            Object obj = new Object();
            Boolean boolean = (obj is Object);
            Console.WriteLine(boolean);
        }

    is操作符永遠不會拋出異常,這是值得注意的。我們經常像是這樣使用is操作符:

 public static void Main(String[] args)
        {
            int number = 5;
            float f = 6.0F;
            Show(number);
            Show(f);

        }
        public static void Show(Object number)
        {
            if (number is int)
            {
                Console.WriteLine(number);
            }
            else
            {
                Console.WriteLine("請重新輸入一個整數");
            }
        }

     嗯,java的instanceof關鍵字跑到我腦海中了,如果沒有學過java,請無視這句。

    as操作符用於簡化類型轉換:

 public static void Main(String[] args)
        {
            Object obj = new Object();
            People people = obj as People;
            Show(people);
        }

        public static void Show(Object obj)
        {
            if (obj is People)
            {
                Console.WriteLine(obj);
            }
            else
            {
                Console.WriteLine("請給我一個人");
            }
        }

        class People
        {
            private String _Name = "";

            public override String ToString()
            {
                return _Name;
            }
        }

       as操作更多是簡化我們上面的is操作:

        public static void Show(Object obj)
        {
            People people = obj as People;
            if (people != null)
            {
                Console.WriteLine(people);
            }
            else
            {
                Console.WriteLine("請給我一個人");
            }
        }

     如果as操作符進行轉換時,發現類型不匹配,並不會報錯而是返回一個null。
     C#中有很多神奇的東西,值得我們繼續研究下去。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM