C#基礎知識整理:基礎知識(11) 值類型,參考類型

黄舟
發布: 2017-02-11 13:25:40
原創
1116 人瀏覽過

C#是物件導向的語言,在物件導向的思想中,只有對象,所有事物都可以用類別來描述。所以例如這些,int,bool,char,string,double,long等都是類,那麼像,30,2.5,"test"都是對應類別的一個物件。

        static void Main(string[] args)
        {
            string istring = 30.ToString();

            string dstring = 2.5.ToString();

            string sstring = "test".ToString();

            Console.WriteLine(string.Format("{0},{1},{2}", istring, dstring, sstring));

            Console.ReadLine();
        }
登入後複製

輸出:

 可以看出它們有ToString()這個方法,所以它們是物件。
 在平常寫程式碼時,定義資料型別除了上述的這種之外,肯定都用過:

         static void Main(string[] args)
        {
            Int32 i = 0;

            UInt32 j = 0;

            String str = "test";

            Console.ReadLine();
        }
登入後複製

    這個其實是.NET的一個機制,.NET是一個平台,這個平台上有C#,VB這些語言。因此,.NET定義了一系列類型,而映射到不同的語言中,Int32在c#中就是int。這樣的資料類型稱為基元類型,在C#中類別的物件必須使用new生成。而這一部分類別直接就可以用常數表示。基元類型定義在.net Framework中,System命名空間下。看一下基元類型在C#語言中的類型對應。

true/falsebyte0 ~255無符號8位整數yst-128 ~ 127有符號8位元整數char0 ~ 65,535無符號16位元整數 ~ ,767-9,223,372,036,854,775,808 ~9,223,372,036,854,7755807 em.UInt64ulong無符號64位元整數±1.5 × 10 ~ ±3.4 × 10±5.0 × 10 到±1.7 × 10yst364% decimal -2828System.UInt32
.NET Framework基元類型

C#型

System.Booleanbool

/

System.Byte

yst

System.Char

有符號16位元整數
System.UInt16ushort0 ~ 65,535無符號16位元整數
2,147,483,647有符號32位元整數

System .Int64
long
0 ~ 18,446,744,073,709,551,615
System.Singlefloat
-4538

(7位元有效數字)

38

double
-324308

(15至16位元有效數字)

yst
±1.0 × 10 到±7.9 × 10

(27至28位元有效數)yst f3128位元數位浮點數

任意字串

/
uint0 ~ 4,294,967,295符號32位元整數

表中的除了string是引用类型(后面单独解释),其它都是值类型。
下面简单介绍下引用类型和值类型。
学习C语言的时候有个堆和栈的概念。
堆区——程序员分配释放,或者程序结束有OS回收,分配方式类似于链表。
栈区——由编译器自动分配释放,存放函数的参数值,变量值等。
栈内存结构可以快速的分配内存和回收内存,但栈空间有限,过多使用会“溢出”,因此栈只分配常用的,占用空间小的数据类型;堆内存结构分配内存较慢,但是利用空间大,可以存放大型数据。
在C#中,基本上所有的数据都存储在“堆”结构中,称之为“托管堆”,受.NET垃圾回收监控。但是相对于栈堆结构中内存分配效率比较低。为了正确进行垃圾回收,每次分配的堆空间比实际所需空间稍大,小型数据使用堆是不太合适的。
可以比较看一下值类型和引用类型:
C#中提供了Struct定义值类型,直接在栈上分配内存。

 /// <summary>
    /// 使用struct定义一个值类型,
    /// 值类型的只能实现接口,不能继承类
    /// </summary>
    public struct StructPositiveNumber : ICloneable  
    {
        /// <summary>
        /// 值类型字段
        /// </summary>
        private int number;

        /// <summary>
        /// 静态只读字段,作为类的初始值
        /// </summary>
        public readonly static StructPositiveNumber InitialValue = new StructPositiveNumber();

        /// <summary>
        /// 属性
        /// </summary>
        public int Number
        {
            get
            {
                return number;
            }

            set
            {
                if (value <= 0)
                {
                    throw new Exception();
                }

                this.number = value;
            }
        }
        /// <summary>
        /// 可以定义构造器,但是和类不同,这里的默认构造器依然存在
        /// </summary>
        public StructPositiveNumber(int value)
        {
            if (value <= 0)
            {
                throw new Exception();
            }

            this.number = value;
        }

        /// <summary>
        /// 实现克隆方法,返回当前对象
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return new StructPositiveNumber(this.number);
        }
    }
登入後複製

调用

       static void Main(string[] args)
        {
            //声明变量,赋值
            StructPositiveNumber pNumber1 = StructPositiveNumber.InitialValue;

            pNumber1.Number = 1;

            //pNumber1赋给pNumber2
            StructPositiveNumber pNumber2 = pNumber1;

            //改变pNumber2的值
            pNumber2.Number = 2;

            //看打印结果,改变了pNumber2的值,但是不影响pNumber1
            Console.WriteLine(pNumber1.Number);//1

            Console.WriteLine(pNumber2.Number);//2

            //重新初始化pNumber2,通过构造器生成改变了初始值。
            pNumber2 = new StructPositiveNumber(3);

            Console.WriteLine(pNumber2.Number);//3

            //调用Clone将pNumber2复制给pNumber1
            pNumber1 = (StructPositiveNumber)pNumber2.Clone();

            Console.WriteLine(pNumber1.Number);//3

            //改变pNumber1的值,但是pNumber2值不改变
            pNumber1.Number = 4;

            Console.WriteLine(pNumber1.Number);//4

            Console.WriteLine(pNumber2.Number);//3

            Console.ReadLine();
        }
登入後複製

结果

再看引用类型定义的:

 public class ClassPositiveNumber : ICloneable
    {
        private int number;

        public int Number
        {
            get
            {
                return this.number;
            }

            set
            {
                if (value <= 0)
                {
                    throw new Exception();
                }

                this.number = value;
            }
        }

        //引用类型自己可以初始化为null,无需定义初始值
        //public readonly static ClassPositiveNumber InitialValue = new ClassPositiveNumber();

        public ClassPositiveNumber(int value)
        {
            if (value <= 0)
            {
                throw new Exception();
            }

            this.number = value;
        }

        public object Clone()
        {
            return new ClassPositiveNumber(this.number);
        }
    }
登入後複製

调用

      static void Main(string[] args)
        {
            ClassPositiveNumber cNumber1;//默认值为null

            cNumber1 = new ClassPositiveNumber(1);

            ClassPositiveNumber cNumber2 = cNumber1;

            cNumber2.Number = 2;

            //可以看出,两个引用引用到了相同的对象
            Console.WriteLine(cNumber1.Number);//2

            Console.WriteLine(cNumber2.Number);//2

            //重新初始化cNumber2,之前的对象已被丢弃
            cNumber2 = new ClassPositiveNumber(3);

            Console.WriteLine(cNumber2.Number);//3
            
            //复制是复制一个对象的副本,因此,是两个不同的对象
            cNumber1 = (ClassPositiveNumber)cNumber2.Clone();

            Console.WriteLine(cNumber1.Number);//3

            cNumber1.Number = 4;

            Console.WriteLine(cNumber1.Number);//4

            Console.WriteLine(cNumber2.Number);//3

            Console.ReadLine();
        }
登入後複製

结果

通过例子,可以看出值类型的特点如下:
a、使用struct声明;
b、不能继承类,但是可以实现接口(当然除object类外);
c、值类型使用值类型做为字段,但是字段无法有默认值;
c、值类型中必须有默认构造器,而且自己定义构造器后,默认的无参数的构造器依然存在。而且在构造其中只能访问类中的字段,但是不能访问属性。符号=对于值类型来说是赋值,所以赋值是值类型变量不能为空,因为值类型没有引用的概念,肯定有值。

以上就是C#基础知识整理:基础知识(11) 值类型,引用类型的内容,更多相关内容请关注PHP中文网(www.php.cn)!


來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!