[英]List<int> in c#
我無法理解List<int>
背后的邏輯,因為它打破了一些基本規則。
List<int>
應該是值類型而不是引用類型。
ref
關鍵字傳遞List<int>
。 所以這意味着它正在顯示類似於int的值類型行為。 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關於此主題的文章,該文章將為您提供大量示例代碼示例:
不要把它想象成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.