簡體   English   中英

名單 <int> 在c#中

[英]List<int> in c#

我無法理解List<int>背后的邏輯,因為它打破了一些基本規則。

List<int>應該是值類型而不是引用類型。

  1. 如果必須在函數調用之間保持其值,則必須通過ref關鍵字傳遞List<int> 所以這意味着它正在顯示類似於int的值類型行為。
  2. 但是List<int>必須由new運算符初始化。 List<int>也可以為null。 這意味着引用類型行為。

可空類型是不同的,因為它不必由新運算符初始化。

我在這看錯了嗎?

EDITED-

我應該在原始問題中發布代碼。 但它遵循 -

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ListTest d = new ListTest();
            d.Test();
        }
    }

    class ListTest
    {
        public void  ModifyIt(List<int> l)
        {
            l = returnList();
        }

        public void Test()
        {
            List<int> listIsARefType = new List<int>();
            ModifyIt(listIsARefType);
            Console.WriteLine(listIsARefType.Count); // should have been 1 but is 0
            Console.ReadKey(true);
        }

        public List<int> returnList()
        {
            List<int> t = new List<int>();
            t.Add(1);
            return t;
        }
    }
}

列表應該是值類型而不是引用類型。

錯誤! int是值類型。 List<int>是引用類型。

我認為你的第一顆子彈中有一個錯誤的假設。 通用List對象絕對是引用類型(在堆上,而不是堆棧)。 不確定為什么你認為你必須通過ref 這打印“2”就像它應該:

namespace ConsoleApplication1 {
   class Program {
      static void Main(string[] args) {
         List<int> listIsARefType = new List<int>();
         ModifyIt(listIsARefType);
         ModifyIt(listIsARefType);
         Console.WriteLine(listIsARefType.Count); // 2!
         Console.ReadKey(true);
      }

      static void ModifyIt(List<int> l) {
         l.Add(0);
      }
   }
}

您需要了解傳遞引用傳遞值按值傳遞引用之間的區別。

在您發布的代碼示例中,要傳遞的參考 List<int>對象。 這意味着您可以改變引用指向的對象,並且調用代碼將看到這些更改。 但是,引用本身是按值傳遞的,因此如果將引用更改為指向另一個對象,則調用代碼將不會看到更改。

當您使用ref關鍵字時,您將通過引用傳遞引用。 這意味着您不僅可以更改引用指向的對象,還可以更改引用本身。

考慮這個例子:

class Program
{
    static void Main()
    {
        int foo = 0;
        DoSomething1(foo);
        Console.WriteLine(foo); // Outputs 0.

        DoSomething1(ref foo);
        Console.WriteLine(foo); // Outputs 1.

        var bar = new List<int>();
        DoSomething2(bar);
        Console.WriteLine(bar.Count); // Outputs 1.

        DoSomething2(ref bar);
        Console.WriteLine(bar.Count); // Outputs 0.
    }

    // Pass by value.
    static void DoSomething1(int number)
    {
        // Can't modify the number!
        number++;
    }

    // Pass by value.
    static void DoSomething1(ref int number)
    {
        // Can modify the number!
        number++;
    }

    // Pass reference by value.
    static void DoSomething2(List<int> list)
    {
        // Can't change the reference, but can mutate the object.
        list.Add(25);
    }

    // Pass reference by reference.
    static void DoSomething2(ref List<int> list)
    {
        // Can change the reference (and mutate the object).
        list = new List<int>();
    }
}

List<int>確實是一個引用類型。 但列表中包含的項目是值類型。

然而,可以為Nullable的類型實現為結構( struct Nullable<T> where T : struct ),因此是值類型。 你可以簡單寫的原因

int? i = 3;

沒有new關鍵字的是上述語法由編譯器自動轉換為將執行以下操作的代碼:

Nullable<Int32> i = new Nullable<Int32>(3);

為了更好地理解值類型和引用類型語義之間的差異,我建議您閱讀Jon Skeet關於此主題的文章,該文章將為您提供大量示例代碼示例:

Jon Skeet:C#中的參數傳遞

不要把它想象成List<int>以它寫成List<t>的方式來思考它。

List是一個泛型類 它不是結構。 它是一個可以使用值類型和引用類型的泛型類。

List是一種通用引用類型,您使用值類型為int的類型。 但它仍然是一種參考類型。

在ModifyIt()方法中,當你寫'l = returnList()'時; 'l'現在指向內存中的不同位置,而不是Test()方法中listIsARefType的位置。 基本上通過寫'l''='某事,你打破了'l'和'listIsARefType'之間的聯系。 為了保持鏈接(確保兩個對象,'l'和'listIsARefType'指向內存中的相同位置),您需要只處理'l'對象(例如通過調用對象上的函數),或在ModifyIt()方法的參數中使用ref關鍵字。

List<int>是引用類型。 並且它不必作為參考傳遞。

類型列表的對象是值類型一種-的,不同的是值類型的對象可能最終裝箱(轉換成某種引用類型的對象),無論如何,一旦你明白so..scratch這一段。

除了在其他答案中處理的錯誤假設之外,你說:

List<int>必須由new運算符初始化...這意味着引用類型行為。

不,在C#中, new運算符只是調用類型構造函數的語法。 它用於引用和用戶定義的值類型( struct )。

暫無
暫無

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

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