C# 值类型与类的不同

关于值类型和引用类型的区别网上很多,可参考http://blog.yesky.com/Blog/os586/archive/2005/06/07/141356.html今天稍微总结一下,概念性的东西大体一说,C#的所有值类型均隐式派生自System.ValueType,需要注意System.ValueType确是一种引用类型,并且继承System.Object,而所有的引用类型均继承System.Object,值类型存储在堆栈上而引用类型处处在托管堆。
结构是值类型,首先 NEW 在结构的使用有 类类型有所不同,
类类型使用new 是调用构造函数在托管堆分配内存存储空间,返回其地址。而结构类型使用new 不会分配托管堆分配内存而是调用构造函数初始化字段。结构的构造函数要么是有参数的,不可能是无参数,应为无参数是系统自己隐式添加的,就算有另外的构造函数,如果你显示的声明一个无参数的构造函数在结构里,将导致编译错误。

结构的是值类型 存储在栈中,值类型的变量即包括变量地址和变量内容所以可以直接像int ,double ..等使用,不要需要new 使用new 只是说可以方便一点初始化字段,但需要自己添加构造函数。
struct my
{
int x;
int y;
my(int x,int y)
{this.x=x;this.y=y}
}

my mytest=new my(10,10);
这样mytest.x 和mytest.y 都初始化为10;
结构还可以这么初始化
my mytest; 现在的mytest 数据值类型变量
mytest.x=XX;

而引用类型就不允许这么做,引用类型存储其地址,所以需要使用new返回地址及分配空间。

不能在结构中初始化字段,
比如
struct my
{
int x=10;
}
将导致编译错误,因为my现在属于一个数据类型,它不占用存储空间,只有在定义变量的时候才能初始化使用
struct my
{
int x;
}
my mytest;
mytest.x=10;

int x;和my  mytest;
是一样的道理
这的x、struct都是值类型的

我这里介绍的值类型是大家平常不太关注的地方。
首先我们需要知道的是每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值。
比如int i = new int()<==> Int32 i = new Int32() <==> int i = 0<==>Int32 i = 0;
使用new运算符时,将调用特定类型的默认构造函数并对变量赋以默认值.
这里需要注意的是struct的new操作是不执行分配内存操作的(与class的new不同),
其new操作只执行初始化数据操作。
看一个例子
int i = new int();
Console.WriteLine(i);
然而,下面的代码却导致了编译器错误 CS0165,因为它没有使用 new,而且试图使用尚未初始化的对象:
int i;
Console.WriteLine(i);
再看
using System;
using System.Collections.Generic;
using System.Text;

namespace fanxing
...{
    public struct Address
    ...{
        private string _city;
        private string _province;
        private int _zipCode;
      
        //private int _zipCode=0;结构中不能有实例字段初始值设定

        public Address(string city, string province, int zipCode)
        ...{
            _city = city;
            _province = province;
            _zipCode = zipCode;
     
        }

        /**//*public Address(string city, string province)
        {
            _city = city;
            _province = province;
        }如果建立有参构造函数,必须对所有的域字段全部复制*/


        //public Address()
        //{
        //会提示结构不能包含显示无参数构造函数
        //}

        public string City
        ...{
            get ...{ return _city; }
        }
        public string Province
        ...{
            get ...{ return _province; }
        }
        public int ZipCode
        ...{
            get ...{ return _zipCode; }
        }
    }

    public class Address1
    ...{
        private string _city;
        private string _province;
        //private int _zipCode;
        private int _zipCode = 0;
        public static int aaa=8;

        static  Address1()
        ...{
            aaa = 10;
            Console.Write(aaa);
        }

        public Address1()
        ...{

        }

       public Address1(string city, string province)
        ...{
            _city = city;
            _province = province;
            aaa = 20;
            Console.Write(aaa);
        }

        public string City
        ...{
            get ...{ return _city; }
        }
        public string Province
        ...{
            get ...{ return _province; }
        }
        public int ZipCode
        ...{
            get ...{ return _zipCode; }
        }
    }

    class Application1234
    ...{
        static void Main(string[] args)
        ...{
            Address a;
            //int i;
            //Console.WriteLine(i);
            //Console.Write(a.ZipCode);//如果没有new,就会提示使用了未赋值的局部变量a
            a = new Address();
            //Console.Write(a.City + a.ZipCode);//null + 0

            Console.Write(Address1.aaa);
            //在这里特意介绍下static构造函数的用法,
            //不管是实例化还是调用静态变量,静态构造函数只调用一次,并且它先于非静态构造函数前调用。
            Address1 b = new Address1("a","b");
            //Console.Write(b.City + b.ZipCode);//null + 0
            Console.Read();
        }
    }
}
同样道理作为struct来讲,必须通过new进行初始化,但是 structs 不能包含显式默认构造函数,因为编译器将自动提供一个构造函数。此构造函数会将 struct 中的每个字段初始化为默认值(默认情况下,不管是类还是在结构当中CLR会自动将值类型设为0,引用类型默认为null),只有当 struct 用 new 实例化时,才会调用此默认构造函数。

接下来注意这个问题:基于 structs 的对象(包括所有内置数值类型)可以初始化或赋值后使用,如下面的示例所示:
int a = 44;  // Initialize the value type...
int b;
b = 33;      // Or assign it before using it.
Console.WriteLine("{0}, {1}", a, b);也就是说对值类型调用默认构造函数不是必需的。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xiaolei1982/archive/2008/05/08/2416544.aspx

原文地址:https://www.cnblogs.com/jazzka702/p/1503252.html