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#中有很多神奇的东西,值得我们继续研究下去。

posted @ 2013-03-11 16:29  文酱  阅读(2402)  评论(2编辑  收藏  举报