簡體   English   中英

與c#中的值類型和引用類型混淆

[英]confusion with value type and reference type in c#

我對參數有點困惑。 當我們在使用c#中的方法/函數進行編程時,我們應該使用引用參數和什么時候必須使用值類型參數?

您需要非常清楚引用類型與值類型之間的區別,以及“按值”參數與“按引用”參數之間的區別。

我有關於這兩個主題的文章:

當使用作為引用類型的“by value”參數時,這兩者相互作用:在這種情況下,按值復制的值是引用本身; 您仍然可以修改引用引用的對象:

void SomeMethod(StringBuilder x)
{
    x.Append("Modified");
}
...

StringBuilder builder = new StringBuilder();
SomeMethod(builder);
Console.WriteLine(builder.ToString()); // Writes "Modified"

請注意,這是不一樣的東西傳遞by-reference語義......如果SomeMethod發生了變化,包括:

x = null;

那么這不會使builder變量為null。 但是,如果您還將 x參數更改為ref StringBuilder x (並相應地更改了調用代碼),則調用者看到對x任何更改(例如將其設置為null)。

在設計自己的API時,我強烈建議您幾乎不要使用refout參數。 偶爾它們可能很有用,但通常它們表明你試圖從單個方法返回多個值,這通常使用專門封裝這些值的類型更好,或者如果你使用的話可能是Tuple類型.NET 4.當然,這條規則有例外,但這是一個很好的起點。

如果使用值類型參數,則無法在方法中更改其值(您可以但這不會反映用於調用方法的變量),而對於引用類型,您可以更改值。

發送Value類型參數時,內部會將原始變量的副本發送到函數/方法。 因此,如果您更改該函數內的值,則變量的原始值(我們在聲明它的函數中)保持不變。

發送引用類型參數時,該函數直接使用該變量的原始值。 這是因為您只將該變量的內存引用發送給您的函數。

因此,根據變量的范圍以及您希望如何在應用程序中使用該變量,您可以決定如何將其發送到您的函數。 一個很好的例子可能是..如果你想在你的應用程序中計算更新一些全局計數器或狀態變量,那么最好通過ref發送它,以便其他函數將在以后獲得該變量的最新最新值。

有關此主題的最佳文章:

.NET中的C#堆(堆)與堆棧(轉換):第一部分

有四個部分。

您可以嘗試以下簡單代碼,我認為它可以幫助您更好地了解何時使用by-reference參數。

using System.Collections.Generic;
using System.Diagnostics.Contracts;

class Program
{
    static void Main(string[] args)
    {
        var list = new List<int>(new[] { 1, 2, 3, 4 });

        MakeItNull(list);
        Contract.Assert(list != null);

        MakeItRealNull(ref list);
        Contract.Assert(list == null);
    }


    static void MakeItNull(List<int> list)
    {
        list = null;
    }

    static void MakeItRealNull(ref List<int> list)
    {
        list = null;
    }
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM