ฉันรู้ว่า int เป็นประเภทค่า แต่อาร์เรย์ประเภทค่าคืออะไร ประเภทอ้างอิง? ประเภทมูลค่า? ฉันต้องการส่งอาร์เรย์ไปยังฟังก์ชันเพื่อตรวจสอบบางสิ่ง ฉันควรส่งอาร์เรย์หรือไม่เพราะมันจะผ่านการอ้างอิงของมันหรือฉันควรจะส่งผ่านเป็น ref?
ฉันรู้ว่า int เป็นประเภทค่า แต่อาร์เรย์ประเภทค่าคืออะไร ประเภทอ้างอิง? ประเภทมูลค่า? ฉันต้องการส่งอาร์เรย์ไปยังฟังก์ชันเพื่อตรวจสอบบางสิ่ง ฉันควรส่งอาร์เรย์หรือไม่เพราะมันจะผ่านการอ้างอิงของมันหรือฉันควรจะส่งผ่านเป็น ref?
คำตอบ:
อาร์เรย์เป็นกลไกที่ช่วยให้คุณจัดการหลายรายการเป็นคอลเลกชันเดียว Microsoft® .NET Common Language Runtime (CLR) สนับสนุนอาร์เรย์แบบมิติเดียวอาร์เรย์หลายมิติและอาร์เรย์แบบหยัก (อาร์เรย์ของอาร์เรย์) ประเภทอาร์เรย์ทั้งหมดได้มาโดยปริยายจาก System.Array ซึ่งมาจาก System.Object ซึ่งหมายความว่า อาร์เรย์ทั้งหมดเป็นประเภทอ้างอิง ที่จัดสรรบนฮีปที่มีการจัดการเสมอและตัวแปรของแอปของคุณมีการอ้างอิงไปยังอาร์เรย์ไม่ใช่อาร์เรย์เอง
การทดสอบประเภทอ้างอิงเทียบกับชนิดค่าที่ง่ายที่สุดคือชนิดอ้างอิงได้nullแต่ประเภทค่าไม่สามารถทำได้
อาร์เรย์ (แม้กระทั่งชนิดของค่าเช่น int) เป็นประเภทอ้างอิงใน C #
http://msdn.microsoft.com/en-us/library/aa288453(VS.71).aspx :
ใน C # อาร์เรย์เป็นวัตถุ System.Array เป็นประเภทฐานนามธรรมของอาร์เรย์ทุกประเภท
ก่อนอื่นฉันอยากจะบอกคุณว่า Array เป็นประเภทอ้างอิง ทำไม? ฉันอธิบายโยนตัวอย่างหนึ่งตรงนี้
ตัวอย่าง:
int val = 0; // this is a value type ok
int[] val1 = new int[20] // this is a reference type because space required to store 20 integer value that make array allocated on the heap.
นอกจากนี้ประเภทการอ้างอิงยังสามารถเป็นค่าว่างได้ในขณะที่ประเภทค่าไม่สามารถทำได้
ประเภทค่าที่จัดเก็บใน Stack และประเภทการอ้างอิงที่จัดเก็บใน Heap
คุณสามารถส่งอาร์เรย์ไปยังฟังก์ชันโดยใช้ out หรือ ref วิธีการเริ่มต้นเท่านั้นที่แตกต่างกัน
ทดสอบเพื่อตรวจสอบว่าเป็นการอ้างอิงหรือประเภทค่า:
// we create a simple array of int
var a1 = new int[]{1,2,3};
// copy the array a1 to a2
var a2 = a1;
// modify the first element of a1
a1[0]=2;
// output the first element of a1 and a2
Console.WriteLine("a1:"+a1[0]); // 2
Console.WriteLine("a2:"+a2[0]); // 2
//**************************
// all the two variable point to the same array
// it's reference type!
//**************************
คุณสามารถทดสอบออนไลน์ได้ที่https://dotnetfiddle.net/UWFP45
อาร์เรย์เองเป็นชนิดอ้างอิง ค่าของอาร์เรย์นั้นคือค่าหรือประเภทการอ้างอิงตามที่กำหนดโดยชนิดข้อมูลอาร์เรย์ ในตัวอย่างของคุณอาร์เรย์คือประเภทการอ้างอิงและค่าคือประเภทค่า
ทั้งหมดเดียวมิติอาร์เรย์โดยปริยายใช้IList<T>ที่<T>เป็นชนิดข้อมูลของอาร์เรย์ คุณสามารถใช้อินเทอร์เฟซนั้นเป็นชนิดข้อมูลของพารามิเตอร์วิธีการของคุณแทนได้ คุณยังสามารถใช้IEnumerable<T>สำหรับประเภทข้อมูล ไม่ว่าในกรณีใด (หรือแม้ว่าคุณจะใช้เพียงอย่างเดียวint[]) คุณไม่จำเป็นต้องส่งผ่านเป็นrefพารามิเตอร์อย่างชัดเจน
// การอ้างอิงไปยังอาร์เรย์ถูกส่งผ่านด้วยค่า นี่คือที่มาของความ :-) สับสน ...
int[] test = { 1, 2, 3, 4 };
modifContenuSansRef(test);
Console.WriteLine(test[0]); // OK --> 99 le contenu du tableau est modifié
modifTailleSansRef(test);
Console.WriteLine(test.Length); // KO --> 4 La taille n'est pas modifiée
}
static void modifContenuSansRef(int[] t)
{
t[0] = 99;
}
static void modifTailleSansRef(int[] t)
{
Array.Resize(ref t, 8);
}
อาร์เรย์เป็นชนิดอ้างอิงเสมอไม่สำคัญว่าอาร์เรย์จะมีประเภทค่าเช่น int หรือชนิดการอ้างอิงเช่นสตริงเมื่อคุณประกาศอาร์เรย์เช่น
int[] integers=new int[10];
ตัวแปรจำนวนเต็มมีเพียงการอ้างอิงไปยังอาร์เรย์ซึ่งจะอยู่ในฮีป
นอกจากนี้ยังมีหลายคนพูดถึงว่าคุณอาจแตกต่างประเภทค่าจากประเภทการอ้างอิงเพียงขึ้นอยู่กับความจริงที่ว่าตัวแปรอาจเป็นโมฆะหรือไม่ก็ได้ ฉันอยากจะพูดถึงว่าในประเภทค่าปัจจุบันของ c # สามารถเป็นค่าว่างได้
เช่น
int? integer=null
และไม่ใช่วิธีที่ดีในการระบุประเภทคือการอ้างอิงหรือค่าขึ้นอยู่กับตัวแปร fact อาจเป็นโมฆะหรือไม่ก็ได้
ข้อมูลเชิงลึกเพียงเล็กน้อย:
ตัวอย่างเช่นintแทนจำนวนเต็มเดียวint[]แทนอาร์เรย์ของจำนวนเต็ม
ในการเริ่มต้นอาร์เรย์ด้วยมิติข้อมูลเฉพาะคุณสามารถใช้newคำสำคัญโดยกำหนดขนาดไว้ในวงเล็บเหลี่ยมหลังชื่อประเภท:
//create a new array of 32 ints.
int[] integers = new int[32];
อาร์เรย์ทั้งหมดเป็นประเภทอ้างอิงและเป็นไปตามความหมายอ้างอิง ดังนั้นในรหัสนี้แม้ว่าแต่ละองค์ประกอบจะเป็นประเภทค่าดั้งเดิมintegersอาร์เรย์เป็นประเภทอ้างอิง ดังนั้นหากคุณเขียนในภายหลัง:
int[] copy = integers;
สิ่งนี้จะกำหนดสำเนาตัวแปรทั้งหมดเพื่ออ้างถึงอาร์เรย์เดียวกันโดยจะไม่สร้างอาร์เรย์ใหม่
ไวยากรณ์อาร์เรย์ของ C # มีความยืดหยุ่นช่วยให้คุณสามารถประกาศอาร์เรย์โดยไม่ต้องกำหนดค่าเริ่มต้นเพื่อให้อาร์เรย์มีขนาดแบบไดนามิกในโปรแกรมในภายหลัง ด้วยเทคนิคนี้โดยพื้นฐานแล้วคุณกำลังสร้างการอ้างอิงที่เป็นโมฆะและต่อมาก็ชี้การอ้างอิงนั้นไปยังตำแหน่งหน่วยความจำที่จัดสรรแบบไดนามิกที่ร้องขอด้วยnewคำสำคัญ
int[] integers;
integers = new int[32];
ขอบคุณ.