精华内容
下载资源
问答
  • 值类型和引用类型有什么区别?

    千次阅读 2018-03-11 17:22:15
    byte,short,int,long,float,double,decimal,char,bool 和 struct 统称为值类型。string,类等皆为引用类型。值类型变量声明后,不管是否已经赋值,编译器为其分配内存。此时该值存储于栈上;int i=10;执行...

    byteshortintlongfloatdoubledecimalcharbool struct 统称为值类型。

    string,类等皆为引用类型。

    值类型变量声明后,不管是否已经赋值,编译器为其分配内存。此时该值存储于栈上;int i=10;执行之前为默认一个值0。

    引用类型定义时在栈上开辟一个空间用来存放其在堆上的地址,当赋值或者实例化时候就会在堆上开辟一个空间,然后把堆中的地址存放在栈中,这时候栈就存放了其地址。

    内存分配如下图:

    引用传递的另外一个实例



    为了解决频繁的装箱和拆箱消耗资源,引入了泛型的概念,泛型是类,是引用类型,但是在自己内部做了特殊的处理,使用过程不会进行装箱拆箱操作


    展开全文
  • C#中什么值类型与引用类型? 值类型:struct、enum、int、float、char、bool、decimal 引用类型:class、delegate、interface、array、object、string

    C#中什么是值类型与引用类型?

    值类型:struct、enum、int、float、char、bool、decimal
    引用类型:class、delegate、interface、array、object、string

    展开全文
  • C#详解值类型和引用类型区别

    万次阅读 多人点赞 2016-04-20 17:59:42
    首先,什么值类型什么是引用类型? 在C#中值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中。 值类型(value type):byte,short,int,long,float,double,decimal,...

    首先,什么是值类型,什么是引用类型?

    在C#中值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中。

    值类型(value type):byte,short,int,long,float,double,decimal,char,bool 和 struct 统称为值类型。值类型变量声明后,不管是否已经赋值,编译器为其分配内存。


            引用类型(reference type):string 和 class统称为引用类型。当声明一个类时,只在栈中分配一小片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间。当使用 new 创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到栈上分配的小片空间中。


    值类型的实例通常是在线程栈上分配的(静态分配),但是在某些情形下可以存储在堆中。引用类型的对象总是在进程堆中分配(动态分配)。

            下面的例子说明值类型和引用类型的区别,代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Parameters
    {
        class Program
        {
            static void Main(string[] args)
            {
                Dowork();
            }
    
            static void Dowork()
            {
                int i = 0;  // int 是值类型
                Console.WriteLine(i);   // i = 0
                Pass.value(i);          // 值类型使用的是 i 的副本,i不变
                Console.WriteLine(i);   // i = 0
    
                WrappendInt wi = new WrappendInt(); // 创建类 WrappendInt 的另外一个实例
                Console.WriteLine(wi.Number);   // 0 // 被默认构造器初始化为 0
                Pass.Reference(wi);     // 调用方法,wi 和 param 将引用同一个对象
                Console.WriteLine(wi.Number);   // 42
            }
        }
    
        class Pass
        {
            public static void value(int param)
            {
                param = 42; // 赋值操作使用的是值类型参数的一个副本,原始参数不受影响
            }
    
            public static void Reference(WrappendInt param) // 创建类 WrappendInt 的一个实例
            {
                param.Number = 42;  // 此参数是引用类型的参数
            }
        }
    
        class WrappendInt   // 类是引用类型
        {
            public int Number;
        }
    }

    输出结果为:

    0

    0

    0

    42


    从概念上看,值类型直接存储其值,而引用类型存储对其值的引用。这两种类型存储在内存的不同地方。在C#中,我们必须在设计类型的时候就决定类型实例的行为。这种决定非常重要,用《CLR via C#》作者Jeffrey Richter的话来说,“不理解引用类型和值类型区别的程序员将会给代码引入诡异的bug和性能问题(I believe that a developer who misunderstands the difference between reference types and value types will introduce subtle bugs and performance issues into their code.)”。这就要求我们正确理解和使用值类型和引用类型。

    1. 通用类型系统

    C#中,变量是值还是引用仅取决于其数据类型。

    C#的基本数据类型都以平台无关的方式来定义。C#的预定义类型并没有内置于语言中,而是内置于.NET Framework中。.NET使用通用类型系统(CTS)定义了可以在中间语言(IL)中使用的预定义数据类型,所有面向.NET的语言都最终被编译为IL,即编译为基于CTS类型的代码。

    例如,在C#中声明一个int变量时,声明的实际上是CTS中System.Int32的一个实例。这具有重要的意义:

    • 确保IL上的强制类型安全;
    • 实现了不同.NET语言的互操作性;
    • 所有的数据类型都是对象。它们可以有方法,属性,等。例如:
    int  i;
    i
     = 1
    ;
    string
      s;
    s
     = i.ToString();

    MSDN的这张图说明了CTS中各个类型是如何相关的。注意,类型的实例可以只是值类型或自描述类型,即使这些类型有子类别也是如此。

    c#中引用类型和值类型的区别

    2. 值类型

    C#的所有值类型均隐式派生自System.ValueType:

    • 结构体:struct(直接派生于System.ValueType);
      • 数值类型:
        • 整型:sbyte(System.SByte的别名),short(System.Int16),int(System.Int32),long(System.Int64),byte(System.Byte),ushort(System.UInt16),uint(System.UInt32),ulong(System.UInt64),char(System.Char);
        • 浮点型:float(System.Single),double(System.Double);
        • 用于财务计算的高精度decimal型:decimal(System.Decimal)。
      • bool型:bool(System.Boolean的别名);
      • 用户定义的结构体(派生于System.ValueType)。
    • 枚举:enum(派生于System.Enum);
    • 可空类型(派生于System.Nullable<T>泛型结构体,T?实际上是System.Nullable<T>的别名)。

    每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值。例如:

    int i = new int();

    等价于:

    Int32 i = new Int32();

    等价于:

    int i = 0;

    等价于:

    Int32 i = 0;

    使用new运算符时,将调用特定类型的默认构造函数并对变量赋以默认值。在上例中,默认构造函数将值0赋给了i。MSDN上有完整的默认值表

    所有的值类型都是密封(seal)的,所以无法派生出新的值类型。

    值得注意的是,引 用类型和值类型都继承自System.Object类。不同的是,几乎所有的引用类型都直接从System.Object继承,而值类型则继承其子类,即 直接继承System.ValueType。System.ValueType直接派生于System.Object。即System.ValueType本身是一个类类型,而不是值类型。其关键在于ValueType重写了Equals()方法,从而对值类型按照实例的值来比较,而不是引用地址来比较。

    可以用Type.IsValueType属性来判断一个类型是否为值类型:

    TestType testType = new  TestType ();
    if
      (testTypetype.GetType().IsValueType)
    {
         Console.WriteLine(
    "{0} is value type."
    , testType.ToString());
    }

    3. 引用类型

    C#有以下一些引用类型:

    • 数组(派生于System.Array)
    • 用户用定义的以下类型:
      • 类:class(派生于System.Object);
      • 接口:interface(接口不是一个“东西”,所以不存在派生于何处的问题。Anders在《C# Programming Language》中说,接口只是表示一种约定[contract]);
      • 委托:delegate(派生于System.Delegate)。
    • object(System.Object的别名);
    • 字符串:string(System.String的别名)。

    可以看出:

    • 引用类型与值类型相同的是,结构体也可以实现接口;
    • 引用类型可以派生出新的类型,而值类型不能;
    • 引用类型可以包含null值,值类型不能(可空类型功能允许将 null 赋给值类型);
    • 引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值。

    对于最后一条,经常混淆的是string。我曾经在一本书的一个早期版本上看到String变量比string变量效率高;我还经常听说String是引用类型,string是值类型,等等。例如:

    string s1 = "Hello, " ;
    string s2 = "world!"
    ;
    string s3 = s1 + s2;//s3 is "Hello, world!"

    这确实看起来像一个值类型的赋值。再如:

    string s1 = "a" ;
    string s2 = s1
    ;
    s1
     = "b";//s2 is still "a"

    改变s1的值对s2没有影响。这更使string看起来像值类型。实际上,这是运算符重载的结果,当s1被改变时,.NET在托管堆上为s1重新分配了内存。这样的目的,是为了将做为引用类型的string实现为通常语义下的字符串。

    4. 值类型和引用类型在内存中的部署

    经常听说,并且经常在书上看到:值类型部署在栈上,引用类型部署在托管堆上。实际上并没有这么简单。

    MSDN上说:托管堆上部署了所有引用类型。这很容易理解。当创建一个应用类型变量时:

    object reference = new object();

    关键字new将在托管堆上分配内存空间,并返回一个该内存空间的地址。左边的reference位于栈上,是一个引用,存储着一个内存地址;而这个地址指向的内存(位于托管堆)里存储着其内容(一个System.Object的实例)。下面为了方便,简称引用类型部署在托管推上。

    再来看值类型。《C#语言规范》上的措辞是“结构体不要求在堆上分配内存(However, unlike classes, structs are value types and do not require heap allocation)”而不是“结构体在栈上分配内存”。这不免容易让人感到困惑:值类型究竟部署在什么地方?

    4.1 数组

    考虑数组:

    int[] reference = new int[100];

    根据定义,数组都是引用类型,所以int数组当然是引用类型(即reference.GetType().IsValueType为false)。

    而int数组的元素都是int,根据定义,int是值类型(即reference[i].GetType().IsValueType为true)。那么引用类型数组中的值类型元素究竟位于栈还是堆?

    如果用WinDbg去看reference[i]在内存中的具体位置,就会发现它们并不在栈上,而是在托管堆上。

    实际上,对于数组:

    TestType[] testTypes = new TestType[100];

    如果TestType是值类型,则会一次在托管堆上为100个值类型的元素分配存储空间,并自动初始化这100个元素,将这100个元素存储到这块内存里。

    如果TestType是引用类型,则会先在托管堆为testTypes分配一次空间,并且这时不会自动初始化任何元素(即testTypes[i]均为null)。等到以后有代码初始化某个元素的时候,这个引用类型元素的存储空间才会被分配在托管堆上。

    4.2 类型嵌套

    更容易让人困惑的是引用类型包含值类型,以及值类型包含引用类型的情况:

    public class  ReferenceTypeClass
    {
        
    private int
      _valueTypeField;
        
    public
      ReferenceTypeClass()
         {
             _valueTypeField
     = 0
    ;
         }
        
    public void
      Method()
         {
            
    int valueTypeLocalVariable = 0
    ;
         }
    }
    ReferenceTypeClass referenceTypeClassInstance
     = new ReferenceTypeClass();//Where is _valueTypeField?

    referenceTypeClassInstance.Method();//Where is valueTypeLocalVariable?

    public struct  ValueTypeStruct
    {
        
    private object
      _referenceTypeField;
        
    public void
      Method()
         {
             _referenceTypeField
     = new object
    ();
            
    object referenceTypeLocalVariable = new object
    ();
         }
    }
    ValueTypeStruct valueTypeStructInstance
     = new
      ValueTypeStruct();
    valueTypeStructInstance.Method();
    //Where is _referenceTypeField?And where is referenceTypeLocalVariable?

    单看valueTypeStructInstance,这是一个结构体实例,感觉似乎是整块扔到栈上的。但是字段_referenceTypeField是引用类型,局部变量referenceTypeLocalVarible也是引用类型。

    referenceTypeClassInstance也有同样的问题,referenceTypeClassInstance本身是引用类型,似乎应该整块部署在托管堆上。但字段_valueTypeField是值类型,局部变量valueTypeLocalVariable也是值类型,它们究竟是在栈上还是在托管堆上?

    规律是:

    • 引用类型部署在托管堆上;
    • 值类型总是分配在它声明的地方:作为字段时,跟随其所属的变量(实例)存储;作为局部变量时,存储在栈上。

    我们来分析一下上面的代码。对于引用类型实例,即referenceTypeClassInstance:

    • 从上下文看,referenceTypeClassInstance是一个局部变量,所以部署在托管堆上,并被栈上的一个引用所持有;
    • 值类型字段_valueTypeField属于引用类型实例referenceTypeClassInstance的一部分,所以跟随引用类型实例referenceTypeClassInstance部署在托管堆上(有点类似于数组的情形);
    • valueTypeLocalVariable是值类型局部变量,所以部署在栈上。

    而对于值类型实例,即valueTypeStruct:

    • 根据上下文,值类型实例valueTypeStructInstance本身是一个局部变量而不是字段,所以位于栈上;
    • 其引用类型字段_referenceTypeField不存在跟随的问题,必然部署在托管堆上,并被一个引用所持有(该引用是valueTypeStruct的一部分,位于栈);
    • 其引用类型局部变量referenceTypeLocalVariable显然部署在托管堆上,并被一个位于栈的引用所持有。

    所以,简单地说“值类型存储在栈上,引用类型存储在托管堆上”是不对的。必须具体情况具体分析。


    5. 辨明值类型和引用类型的使用场合


    在C#中,我们用struct/class来声明一个类型为值类型/引用类型。考虑下面的例子:
    SomeType[] oneTypes = new SomeType[100];
    如 果SomeType是值类型,则只需要一次分配,大小为SomeType的100倍。而如果SomeType是引用类型,刚开始需要100次分配,分配后 数组的各元素值为null,然后再初始化100个元素,结果总共需要进行101次分配。这将消耗更多的时间,造成更多的内存碎片。所以,如果类型的职责主 要是存储数据,值类型比较合适。
    一般来说,值类型(不支持多态)适合存储供 C#应用程序操作的数据,而引用类型(支持多态)应该用于定义应用程序的行为。通常我们创建的引用类型总是多于值类型。如果满足下面情况,那么我们就应该创建为值类型:
    该类型的主要职责用于数据存储。 
    该类型的共有接口完全由一些数据成员存取属性定义。 
    该类型永远不可能有子类。 
    该类型不具有多态行为。


    5. 值类型和引用类型的区别(小结)


    相同点:
    引用类型可以实现接口,值类型当中的结构体也可以实现接口;
    引用类型和值类型都继承自System.Object类。

    1)范围方面
    C#的值类型包括:结构体(数值类型、bool型、用户定义的结构体),枚举,可空类型。
    C#的引用类型包括:数组,用户定义的类、接口、委托,object,字符串。

    2)内存分配方面:

    数组的元素不管是引用类型还是值类型,都存储在托管堆上。

    引用类型在栈中存储一个引用,其实际的存储位置位于托管堆。简称引用类型部署在托管推上。而值类型总是分配在它声明的地方:作为字段时,跟随其所属的变量(实 例)存储;作为局部变量时,存储在栈上。(栈的内存是自动释放的,堆内存是.NET中会由GC来自动释放)

    3)适用场合

    值类型在内存管理方面具有更好的效率,并且不支持多态,适合用做存储数据的载体;引用类型支持多态,适合用于定义应用程序的行为。

    • 引用类型可以派生出新的类型,而值类型不能,因为所有的值类型都是密封(seal)的;
    • 引用类型可以包含null值,值类型不能(可空类型功能允许将 null 赋给值类型,如   int? a = null;  );
    • 引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值。


    值得注意的是,引 用类型和值类型都继承自System.Object类。不同的是,几乎所有的引用类型都直接从System.Object继承,而值类型则继承其子类,即 直接继承System.ValueType。即System.ValueType本身是一个类类型,而不是值类型。其关键在于ValueType重写了Equals()方法,从而对值类型按照实例的值来比较,而不是引用地址来比较。




    展开全文
  • 值类型与引用类型

    千次阅读 2016-03-02 14:39:17
    1. 值类型和引用类型的区别? 2. 结构和类的区别? 3. delegate是引用类型还是值类型?enum、int[]和string呢? 4. 堆和栈的区别? 5. 什么情况下会在堆(栈)上分配数据?它们性能上的区别吗? 6.“结构”...

    1. 值类型和引用类型的区别?

    2. 结构和类的区别?

    3. delegate是引用类型还是值类型?enum、int[]和string呢?

    4. 堆和栈的区别?

    5. 什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?

    6.“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?

    7. 理解参数按值传递?以及按引用传递?

    8. outref 的区别与相同点?

    9. C#支持哪几个预定义的值类型?C#支持哪些预定义的引用类型?

    10. 有几种方法可以判定值类型和引用类型?

    11. 说说值类型和引用类型的生命周期?

    12. 如果结构体中定义引用类型,对象在内存中是如何存储的?例如下面结构体中的class类 User对象是存储在栈上,还是堆上?


    public struct Student
    {
        public int Age;
        public User user;
    }

    认识值类型与引用类型

    基本概念

    CLR支持两只类型:引用类型值类型。这是.NET语言的基础和关键,他们从类型定义、实例创建、参数传递,到内存分配都有所不同。虽然看上去简单,但真正理解其内涵的人却好像并不多。

    下图清晰了展示了.NET中类型分类,值类型主要是一些简单的、基础的数据类型,引用类型主要用于更丰富的、复杂的、复合的数据类型。

    内存结构

    值类型和引用类型最根源的区别就是其内存分配的差异,在这之前首先要理解CLR的内存中两个重要的概念:

    Stack 栈:线程栈,由操作系统管理,存放值类型、引用类型变量(就是引用对象在托管堆上的地址)。栈是基于线程的,也就是说一个线程会包含一个线程栈,线程栈中的值类型在对象作用域结束后会被清理,效率很高。

    GC Heap托管堆:进程初始化后在进程地址空间上划分的内存空间,存储.NET运行过程中的对象,所有的引用类型都分配在托管堆上,托管堆上分配的对象是由GC来管理和释放的。托管堆是基于进程的,当然托管堆内部还有其他更为复杂的结构,有兴趣的可以深入了解。

    结合下图理解,变量a及其值3都是存储在栈上面。变量b在栈上存储,其值指向字符串“123”的托管堆对象地址(字符串是引用类型,字符串对象是存储在托管堆上面。字符串是一个特殊的引用类型,后面文章会专门探讨)”

    值类型一直都存储在栈上面吗?所有的引用类型都存储在托管堆上面吗?

    1.单独的值类型变量,如局部值类型变量都是存储在栈上面的;

    2.当值类型是自定义class的一个字段、属性时,它随引用类型存储在托管堆上,此时她是引用类型的一部分;

    4.所有的引用类型肯定都是存放在托管堆上的。

    5.还有一种情况,同上面题目12,结构体(值类型)中定义引用类型字段,结构体是存储在栈上,其引用变量字段只存储内存地址,指向堆中的引用实例。

    对象的传递

    将值类型的变量赋值给另一个变量(或者作为参数传递),会执行一次值复制。将引用类型的变量赋值给另一个引用类型的变量,它复制的值是引用对象的内存地址,因此赋值后就会多个变量指向同一个引用对象实例。理解这一点非常重要,下面代码测试验证一下:

    int v1 = 0;
    int v2 = v1;
    v2 = 100;
    Console.WriteLine("v1=" + v1); //输出:v1=0
    Console.WriteLine("v2=" + v2); //输出:v2=100
    
    User u1 = new User();
    u1.Age = 0;
    User u2 = u1;
    u2.Age = 100;
    Console.WriteLine("u1.Age=" + u1.Age); //输出:u1.Age=100
    Console.WriteLine("u2.Age=" + u2.Age); //输出:u2.Age=100,因为u1/u2指向同一个对象

    当把对象作为参数传递的时候,效果同上面一样,他们都称为按值传递,但因为值类型和引用类型的区别,导致其产生的效果也不同。

    参数-按值传递:

    private void DoTest(int a)
    {
        a *= 2;
    }
    
    private void DoUserTest(User user)
    {
        user.Age *= 2;
    }
    
    [NUnit.Framework.Test]
    public void DoParaTest()
    {
        int a = 10;
        DoTest(a);
        Console.WriteLine("a=" + a); //输出:a=10
        User user = new User();
        user.Age = 10;
        DoUserTest(user);
        Console.WriteLine("user.Age=" + user.Age); //输出:user.Age=20
    }

    上面的代码示例,两个方法的参数,都是按值传递

    • 对于值类型(int a) :传递的是变量a的值拷贝副本,因此原本的a值并没有改变。
    • 对于引用类型(User user) :传递的是变量user的引用地址(User对象实例的内存地址)拷贝副本,因此他们操作都是同一个User对象实例。

    参数-按引用传递:

    按引用传递的两个主要关键字:out ref不管值类型还是引用类型,按引用传递的效果是一样的,都不传递值副本,而是引用的引用(类似c++的指针的指针)。outref告诉编译器方法传递额是参数地址,而不是参数本身,理解这一点很重要。

    代码简单测试一下,如果换成out效果是相同的

    private void DoTest(ref int a)
    {
        a *= 2;
    }
    
    private void DoUserTest(ref User user)
    {
        user.Age *= 2;
    }
    
    [NUnit.Framework.Test]
    public void DoParaTest()
    {
        int a = 10;
        DoTest(ref a);
        Console.WriteLine("a=" + a); //输出:a=20 ,a的值改变了
        User user = new User();
        user.Age = 10;
        DoUserTest(ref user);
        Console.WriteLine("user.Age=" + user.Age); //输出:user.Age=20
    }

    outref的主要异同

    • outref都指示编译器传递参数地址,在行为上是相同的;
    • 他们的使用机制稍有不同,ref要求参数在使用之前要显式初始化,out要在方法内部初始化;
    • outref不可以重载,就是不能定义Method(ref int a)和Method(out int a)这样的重载,从编译角度看,二者的实质是相同的,只是使用时有区别;
    • 常见问题

    题目答案解析:

    1. 值类型和引用类型的区别?

    值类型包括简单类型、结构体类型和枚举类型,引用类型包括自定义类、数组、接口、委托等。

    • 1、赋值方式:将一个值类型变量赋给另一个值类型变量时,将复制包含的值。这与引用类型变量的赋值不同,引用类型变量的赋值只复制对象的引用(即内存地址,类似C++中的指针),而不复制对象本身。
    • 2、继承:值类型不可能派生出新的类型,所有的值类型均隐式派生自 System.ValueType。但与引用类型相同的是,结构也可以实现接口。
    • 3、null:与引用类型不同,值类型不可能包含 null 值。然而,可空类型功能允许将 null 赋给值类型。
    • 4、每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值,值类型初始会默认为0,引用类型默认为null。
    • 5、值类型存储在栈中,引用类型存储在托管堆中。

    2. 结构和类的区别?

    结构体是值类型,类是引用类型,主要区别如题1。其他的区别:

    • 结构不支持无惨构造函数,不支持析构函数,并且不能有protected修饰;
    • 结构常用于数据存储,类class多用于行为;
    • class需要用new关键字实例化对象,struct可以不适用new关键字;
    • class可以为抽象类,struct不支持抽象;

    3. delegate是引用类型还是值类型?enum、int[]和string呢?

    enum枚举是值类型,其他都是引用类型。

    4. 堆和栈的区别?

    线程堆栈:简称栈 Stack
    托管堆: 简称堆 Heap

    • 值类型大多分配在栈上,引用类型都分配在堆上;
    • 栈由操作系统管理,栈上的变量在其作用域完成后就被释放,效率较高,但空间有限。堆受CLR的GC控制;
    • 栈是基于线程的,每个线程都有自己的线程栈,初始大小为1M。堆是基于进程的,一个进程分配一个堆,堆的大小由GC根据运行情况动态控制;

    6.“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?

    结构是值类型,有两种情况会分配在对上面:

    • 结构作为class的一个字段或属性,会随class一起分配在堆上面;
    • 装箱后会在堆中存储,尽量避免值类型的装箱,值类型的拆箱和装箱都有性能损失,下一篇会重点关注;

    7. 理解参数按值传递?以及按引用传递?

    • 按值传递:对于值类型传递的它的值拷贝副本,而引用类型传递的是引用变量的内存地址,他们还是指向的同一个对象。
    • 按引用传递:通过关键字out和ref传递参数的内存地址,值类型和引用类型的效果是相同的。

    8. outref的区别与相同点?

    • outref都指示编译器传递参数地址,在行为上是相同的;
    • 他们的使用机制稍有不同,ref要求参数在使用之前要显式初始化,out要在方法内部初始化;
    • outref不可以重载,就是不能定义Method(ref int a)和Method(out int a)这样的重载,从编译角度看,二者的实质是相同的,只是使用时有区别;

    9. C#支持哪几个预定义的值类型?C#支持哪些预定义的引用类型?

    值类型:整数、浮点数、字符、bool和decimal

    引用类型:Object,String

    10. 有几种方法可以判定值类型和引用类型?

    简单来说,继承自System.ValueType的是值类型,反之是引用类型。

    11. 说说值类型和引用类型的生命周期?

    值类型在作用域结束后释放。

    引用类型由GC垃圾回收期回收。这个答案可能太简单了,更详细的答案在后面的文章会说到。

    12. 如果结构体中定义引用类型,对象在内存中是如何存储的?例如下面结构体中的class类 User对象是存储在栈上,还是堆上?

    public struct UserStruct
    {
        public int Index;
        public User User;
    }

    UserStruct存储在栈中,其字段User的实例存储在堆中,UserStruct.User字段存储指向User对象的内存地址。

    展开全文
  • golang中的值类型和引用类型

    千次阅读 2019-08-20 20:48:29
    值类型与引用类型 值类型 值类型:这些类型的变量直接指向存在内存中的值,值类型的变量的值存储在栈中。当使用等号=将一个变量的值赋给另一个变量时,如 j = i ,实际上是在内存中将 i 的值进行了拷贝。可以通过 &...
  • C# - 值类型与引用类型

    万次阅读 2019-02-28 19:52:35
    分享一个大牛的人工智能教程。...因此,一个值类型变量永远不会影响到其他的值类型变量,而两个引用类型变量则很可能指向同一地址,从而产生相互影响。 从内存分配上看,值类型分配在线程的栈上,作用...
  • 值类型和引用类型

    千次阅读 热门讨论 2019-01-02 20:18:16
    值类型:直接存储值,在栈上存储其值 注:值类型变量声明后,不管是否已经赋值,编译器为其分配内存 引用类型:存储对其值的引用,在栈上存储地址,在堆上存储值 注:引用类型当声明一个类时,只在栈中分配一小片...
  • java 值类型和引用类型

    千次阅读 2017-09-11 16:34:21
    java这两种数据类型分别哪些?java 中的数据类型分为两大类:值类型(基本数据类型)和引用类型(复合数据类型) ...二,引用值类型 除了值类型外就是引用值类型了,引用值类型有1,类类型(class) 2,数组 3,接口类型
  • C#中引用类型和值类型分别哪些

    万次阅读 2018-06-15 02:12:58
    C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型。 C#的引用类型包括:数组,用户定义的类、接口、委托,object,字符串。 数组的元素,不管是引用类型还是值类型,都存储在托管堆...
  • 关于值类型和引用类型的相关问题

    千次阅读 2019-12-18 00:40:31
    1、什么值类型什么是引用类型? 值类型保存的是具体的值,引用类型保存的是值得地址,例如: Console.WriteLine("值类型,保存的是具体的值"); int x = 1; int y = x; y = y + x; Console.WriteLine("x:...
  • Swift 值类型和引用类型

    万次阅读 2014-08-20 16:58:08
    Swift中的类型分为两类:一,值类型(value types),每个值类型的实例都拥有各自唯一的数据,通常它们是结构体,枚举或元组;二,引用类型(reference types),引用类型的实例共享它们的数据,通常是一个类。在这篇...
  • C# 值类型与引用类型

    千次阅读 2018-07-19 14:31:09
    值类型与引用类型 只所以要提这两个概念,是因为很好得理解这两个概念助于我们写出比较高效的C#代码。 我们知道,C#中的每一种类型要么是值类型,要么是引用类型。所以每个对象要么是值类型的实例,要么是引用...
  • Go语言中的值类型和引用类型

    千次阅读 2018-05-04 20:50:10
    一、值类型和引用类型值类型:int、float、bool和string这些类型都属于值类型,使用这些类型的变量直接指向存在内存中的值,值类型的变量的值存储在栈中。当使用等号=将一个变量的值赋给另一个变量时,如 j = i ,...
  • 值类型和引用类型的区别

    千次阅读 2017-10-25 10:07:08
    值类型表示复制一个当前变量传给方法,当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变。值类型也就是基本数据类型 基本数据类型常被称为四类八种。四类八种: 整型(4种):byte(1 byte)、short(2 ...
  • 一、什么值类型什么是引用类型 概念:值类型直接存储其值,而引用类型存储对其值的引用。部署:托管堆上部署了所有引用类型。 引用类型:基类为Objcet 值类型:均隐式派生自System.ValueType: 值类型...
  • Golang断言判断值类型

    千次阅读 2021-02-04 10:18:53
    v,e:=i.(string)//返回value和error值,当err值为true则转化成功,value的值为括号中的值类型,当err值为false,则转化不成功 也可以通过反射判断值的类型 name:="test" t:=relfect.TypeOf(name) fmt.Println(t)//...
  • 值类型和引用类型深入理解

    万次阅读 2018-08-02 14:19:04
    1.值类型(ValueType) 值类型包括:数值类型,结构体,bool型,用户定义的结构体,枚举,可空类型。 值类型的变量直接存储数据,分配在托管栈中。变量会在创建它们的方法返回时自动释放,例如在一个方法中声明Char...
  • C#中的DateTime是值类型还是引用类型

    千次阅读 2017-04-12 09:29:42
    近期遇到了DateTime到底是值类型还是引用类型的疑惑,顺势较深入地了解一下DateTime相关的内容 结论:DateTime是值类型,因为DateTime是结构体,而结构体继承自System.ValueType,属于值类型   一、DateTime是...
  • Golang学习之路—值类型和引用类型

    千次阅读 2021-02-21 18:22:01
    值类型和引用类型值类型和引用类型说明值类型和引用类型特点值类型引用类型栈区和堆区示意图 值类型和引用类型说明 值类型:基本数据类型int系列,float系列,bool,string,数组和结构体struct。 引用类型:指针、...
  • unity中的值类型和引用类型

    千次阅读 2019-09-03 21:26:24
    一、值类型和引用类型概念 值(value)类型 :Unity中的vector3、quaternion是structs,它们是值。 引用(feference)类型 :Unity中的transform、gameobject是类类型,所以它们是引用。引用类型是对数据存储位置的...
  • js值类型和引用类型的区别

    千次阅读 2018-04-28 10:42:48
    1. javascript中变量类型分为值类型(基本数据类型)和引用类型(1) 值类型:String(字符串),Number(数值),Boolean(布尔值),Undefined,Null(2) 引用类型:Array(数组),Object(对象),Function(函数)2. ...
  • String是值类型还是引用类型(C#)

    千次阅读 2015-08-28 14:22:25
    MSDN 中明确指出 String 是引用类型而不是值类型,但 String 表面上用起来却像是值类型,这又是什么原因呢?
  • 【C#基础】值类型和引用类型

    千次阅读 热门讨论 2016-10-23 18:58:18
    在备战软考的过程中,涉及到了原型模式,其中讲到了在浅复制的过程中,值类型和引用类型是区别的。那么究竟什么值类型什么是引用类型呢? 在理解这两个概念之前,我们先谈一谈栈和堆。
  • Python学习系列之值类型与引用类型

    千次阅读 多人点赞 2019-01-15 00:15:24
    其实各个标准资料中没有说明Python有值类型和引用类型的分类,这个分类一般是C++和Java中的。但是语言是相通的,所以Python肯定也类似的。实际上Python 的变量是没有类型的,这与以往看到的大部分语言都不一样(JS...
  • JAVA值类型和引用类型的区别

    千次阅读 2018-03-04 17:06:19
    JAVA值类型和引用类型的区别定义:引用类型:表示你操作的数据是同一个,也就是说当年传一个参数给另一个方法时,你在另一个方法中改变这个变量的值,那么调用这个方法是所传入的变量的值也将改变值类型:表示复制当前的一...
  • C#里面的值类型与引用类型的区别

    千次阅读 2014-01-04 14:11:08
    C#里面把数据类型分为两大类,分别为值类型和引用类型,值类型包括基本数据类型(int ,double等),结构和枚举,,,引用类型包括接口,数组,Object类型,类,委托,字符串,null类型等,那这两大类有什么区别呢?...
  • JavaScript基本类型和引用类型

    千次阅读 2015-11-01 21:35:37
    JS变量可能包含两种不同数据类型;...JS5种基本数据类型:Undefined, Null,Boolean,Number和String。这5种基本数据类型是按访问的。因为可以操作保存在变量中的实际的。 引用类型保存在内存中的

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,006,537
精华内容 2,002,614
关键字:

值的类型有什么