值類型(Value Types)和引用類型 (Reference Types)的區別

摘要:值類型(Value Types)和引用類型 (Reference Types)的區別

C#中的參數傳遞:值類型(value type)和引用類型(reference type)

大陸翻譯..不太好懂,不管..先留著記錄。

資料來源:http://victor-musiczone.blogspot.com/2011/01/value-types-reference-types.html

  • C#中的參數傳遞的四種形式:值傳遞(默認形式)、ref傳遞、out傳遞、params傳遞
  • 值類型是分配在棧(stack)上面,而引用類型分配在堆(heap)上面
  • 引用類型(reference type):它存放的值是指向數據的引用(reference),而不是數據本身
  • class類型,interface類型,delegate類型和array類型都是引用類型。
  • 值類型的變量直接保存的就是數據
  • 簡單類型(比如int,double,char),enum類型,struct類型都是值類型。
  • 默認情況下,參數都是值參數。
  • 引用類型變量保存的是引用,如果兩個引用類型變量引用到相同的對象,那麼對對象進行修改勢必影響到兩個引用類型變量
  • 引用參數不傳遞在函數成員調用中的變量的值,而是傳遞變量本身。這就意味著它並不會為函數成員聲明中的變量分配新的內存空間,而是使用與實參相同的存儲空間,所以實參和形參的值無論什麼時候都是一樣的。要在C#中使用引用參數,必須在函數聲明以及函數調用中都明確地使用關鍵字ref
  • 變量 --對象引用(變量的值)--對象
  • 輸出參數與引用參數非常相似,除了使用關鍵字out以外,它們的不同點在於ref修飾的形式參數可以不被賦值,而out修飾的形式參數必須被賦值。因此,使用輸出參數的實參可以在調用之前不被初始化
  • 用params修飾的一維數組為參數數組。它可以接收可變數目的實參。C/C++程序員可以認為params等同於類型安全的stdarg.h頭文件中varargs宏。



using System;using System.Collections.Generic;using System.Text;
namespace ConsoleApp1
{
    public class ParamTest
    {
        public StringBuilder first = new StringBuilder();
        public StringBuilder second;
      
        public ParamTest()
        {
            first.Append("first");
            second = first;
        }

        public String First
        {
            get { return first.ToString(); }
        }

        public String Second
        {
            get { return second.ToString(); }
        }
        //引用類型參數,改變引用的對象--ok
        public void SetRefValue(ref StringBuilder sb)
        {
            System.Text.StringBuilder third = new StringBuilder(); ;

            third.Append("SetRefValue");

            sb = third;
        }
        //值類型參數,改變引用的對象--failed
        public void SetValue(StringBuilder sb)
        {
            System.Text.StringBuilder third = new StringBuilder(); ;

            third.Append("SetValue");

            sb = third;
        }
        //值類型參數,改變引用的對象的值----ok
        public void SetObjectValue(StringBuilder sb)
        {
            sb.Append("SetObjectValue ");
        }

        static void Main(string[] args)
        {
            Console.WriteLine("---------------{0}", 55 / 2);
            ParamTest test = new ParamTest();
            Console.WriteLine("--------1-------{0},{1}", test.First, test.Second);
            test.SetObjectValue(test.first);
            Console.WriteLine("--------SetObjectValue-------{0},{1}", test.First, test.Second);
            test.SetValue(test.first);
            Console.WriteLine("--------SetValue-------{0},{1}", test.First, test.Second);
            test.SetRefValue(ref test.first);
            Console.WriteLine("--------SetRefValue-------{0},{1}", test.First, test.Second);

            Console.ReadLine();
        }
    }
}

相關:


MSDN解釋(原文):http://msdn.microsoft.com/en-us/library/2hkbth2a%28VS.71%29.aspx

比較詳細(一樣大陸翻譯..):http://www.cnblogs.com/mrcooldog/archive/2008/03/03/1088769.html