ไวยากรณ์เริ่มต้นของอาร์เรย์ที่เป็นไปได้ทั้งหมด


คำตอบ:


779

นี่คือวิธีการประกาศและการเริ่มต้นในปัจจุบันสำหรับอาร์เรย์อย่างง่าย

string[] array = new string[2]; // creates array of length 2, default values
string[] array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
string[] array = new[] { "A", "B" }; // created populated array of length 2

โปรดทราบว่าเทคนิคอื่น ๆ ของการได้รับอาร์เรย์ที่มีอยู่เช่น Linq ส่วนขยายในToArray()IEnumerable<T>

โปรดทราบว่าในการประกาศด้านบนทั้งสองรายการแรกสามารถแทนที่string[]ด้านซ้ายด้วยvar(C # 3+) เนื่องจากข้อมูลทางด้านขวาเพียงพอที่จะสรุปประเภทที่เหมาะสม บรรทัดที่สามต้องเขียนตามที่แสดงเนื่องจากไวยากรณ์การกำหนดค่าเริ่มต้นของอาเรย์อย่างเดียวไม่เพียงพอที่จะตอบสนองความต้องการของคอมไพเลอร์ ข้อที่สี่อาจใช้การอนุมาน ดังนั้นหากคุณเป็นคนที่มีความกะทัดรัดสามารถเขียนข้างต้นได้

var array = new string[2]; // creates array of length 2, default values
var array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
var array = new[] { "A", "B" }; // created populated array of length 2 

1
จากความอยากรู้อยากเห็นใครช่วยอธิบายว่าทำไมนิพจน์การเริ่มต้นในบรรทัดที่ 3 ไม่สามารถใช้ด้วยตัวเอง (เช่นส่งไปยังเมธอด) หรือกำหนดให้กับvarตัวแปร
Ruben9922

1
@ Ruben9922: คำถามที่น่าสนใจ มันจะทำให้รู้สึกว่าvar x = {}ใช้งานไม่ได้ถ้า initializer อาร์เรย์สามารถให้สิ่งอื่นนอกเหนือจากอาร์เรย์ แต่ฉันจะไม่ทราบว่ามันคืออะไร ดังนั้นฉันเดาว่า initializer อาเรย์เป็นคุณสมบัติภาษา หากคุณใช้กับnew List<string> {"A", "B"}มันจะให้สิ่งที่แตกต่างเช่นกัน
TvdH

441

ไวยากรณ์การสร้างอาร์เรย์ใน C # ที่เป็นนิพจน์คือ:

new int[3]
new int[3] { 10, 20, 30 }
new int[] { 10, 20, 30 }
new[] { 10, 20, 30 }

ในครั้งแรกขนาดอาจเป็นค่าอินทิกรัลที่ไม่เป็นลบใด ๆ และองค์ประกอบอาเรย์จะเริ่มต้นเป็นค่าเริ่มต้น

ในส่วนที่สองขนาดต้องเป็นค่าคงที่และจำนวนองค์ประกอบที่กำหนดต้องตรงกัน จะต้องมีการแปลงโดยนัยจากองค์ประกอบที่กำหนดให้เป็นประเภทองค์ประกอบอาร์เรย์ที่กำหนด

ในองค์ประกอบที่สามองค์ประกอบนั้นจะต้องถูกแปลงให้เป็นประเภทองค์ประกอบโดยปริยายและขนาดจะถูกกำหนดจากจำนวนองค์ประกอบที่กำหนด

ในหนึ่งในสี่ประเภทขององค์ประกอบอาร์เรย์จะอนุมานได้โดยการคำนวณประเภทที่ดีที่สุดถ้ามีหนึ่งในองค์ประกอบที่กำหนดทั้งหมดที่มีประเภท องค์ประกอบทั้งหมดจะต้องถูกแปลงให้เป็นประเภทนั้นโดยปริยาย ขนาดถูกกำหนดจากจำนวนองค์ประกอบที่กำหนด ไวยากรณ์นี้ถูกนำมาใช้ใน C # 3.0

นอกจากนี้ยังมีไวยากรณ์ที่สามารถใช้ในการประกาศเท่านั้น:

int[] x = { 10, 20, 30 };

องค์ประกอบจะต้องถูกแปลงเป็นองค์ประกอบประเภทโดยปริยาย ขนาดถูกกำหนดจากจำนวนองค์ประกอบที่กำหนด

ไม่มีคู่มือแบบครบวงจร

ฉันแนะนำคุณให้ใช้ข้อกำหนด C # 4.0 หัวข้อ 7.6.10.4 "นิพจน์การสร้างอาร์เรย์"


8
@BoltClock: ไวยากรณ์แรกที่คุณพูดถึงคือ "นิพจน์การสร้างอาเรย์ที่พิมพ์โดยปริยาย" ประการที่สองคือ "นิพจน์การสร้างวัตถุที่ไม่ระบุชื่อ" คุณไม่ได้แสดงรายการไวยากรณ์ที่คล้ายกันอีกสองรายการ มันคือ "object initializer" และ "collection initializer"
Eric Lippert

11
ไม่ใช่ไวยากรณ์ของ C # "อย่างแน่นอน แต่อย่าลืม (รายการโปรดส่วนตัวของฉัน) Array.CreateInstance(typeof(int), 3)!
Jeffrey L Whitledge

17
@ เจฟฟรีย์: ถ้าเราไปตามทางนั้นมันจะเริ่มโง่ เช่น"1,2,3,4".split(',').
Brian

11
แล้วสำหรับอาร์เรย์หลายมิติที่มีอยู่ "ที่ซ้อนกัน" ข้อความที่ต้องการnew int[,] { { 3, 7 }, { 103, 107 }, { 10003, 10007 }, };และอื่น ๆ สำหรับint[,,], int[,,,]...
Jeppe เพอร์นีลเซ่น

6
@ Learning-Overthinker-Confused: คุณมีม้าสองตัว คุณต้องการที่จะรู้ว่าเร็วกว่าใคร คุณ (1) แข่งม้าหรือ (2) ถามคนแปลกหน้าบนอินเทอร์เน็ตที่ไม่เคยเห็นม้าตัวที่เขาคิดว่าเร็วกว่านี้หรือไม่? แข่งม้าของคุณ คุณต้องการที่จะรู้ว่า "ประสิทธิภาพ" อันไหนมากกว่ากัน? ขั้นแรกสร้างมาตรฐานที่วัดได้เพื่อประสิทธิภาพ โปรดจำไว้ว่าประสิทธิภาพคือมูลค่าที่ผลิตต่อต้นทุนต่อหน่วยดังนั้นให้กำหนดค่าและราคาของคุณอย่างระมัดระวัง จากนั้นเขียนโค้ดทั้งสองวิธีและวัดประสิทธิภาพ ใช้วิทยาศาสตร์เพื่อตอบคำถามทางวิทยาศาสตร์ไม่ถามคนแปลกหน้าแบบสุ่มเพื่อคาดเดา
Eric Lippert

111

อาร์เรย์ที่ไม่ว่างเปล่า

  • var data0 = new int[3]

  • var data1 = new int[3] { 1, 2, 3 }

  • var data2 = new int[] { 1, 2, 3 }

  • var data3 = new[] { 1, 2, 3 }

  • var data4 = { 1, 2, 3 }ไม่สามารถคอมไพล์ได้ ใช้int[] data5 = { 1, 2, 3 }แทน

อาร์เรย์ที่ว่างเปล่า

  • var data6 = new int[0]
  • var data7 = new int[] { }
  • var data8 = new [] { } และint[] data9 = new [] { }ไม่สามารถคอมไพล์ได้

  • var data10 = { }ไม่สามารถคอมไพล์ได้ ใช้int[] data11 = { } แทน

เป็นอาร์กิวเมนต์ของวิธีการ

นิพจน์ที่สามารถกำหนดด้วยvarคำหลักเท่านั้นที่สามารถส่งผ่านเป็นอาร์กิวเมนต์ได้

  • Foo(new int[2])
  • Foo(new int[2] { 1, 2 })
  • Foo(new int[] { 1, 2 })
  • Foo(new[] { 1, 2 })
  • Foo({ 1, 2 }) ไม่สามารถคอมไพล์ได้
  • Foo(new int[0])
  • Foo(new int[] { })
  • Foo({}) ไม่สามารถคอมไพล์ได้

14
มันเป็นการดีที่จะแยกไวยากรณ์ที่ไม่ถูกต้องออกจากสิ่งที่ถูกต้องให้ชัดเจนยิ่งขึ้น
jpmc26

ตัวอย่างที่ให้มานั้นสมบูรณ์หรือไม่ มีกรณีอื่นอีกไหม?
โปรแกรมเมอร์ที่มุ่งเน้นเงิน

49
Enumerable.Repeat(String.Empty, count).ToArray()

จะสร้างอาร์เรย์ของสตริงว่างซ้ำ 'นับ' ครั้ง ในกรณีที่คุณต้องการเริ่มต้นอาร์เรย์ด้วยค่าองค์ประกอบเริ่มต้นที่เหมือนกัน แต่พิเศษ ระมัดระวังกับประเภทอ้างอิงองค์ประกอบทั้งหมดจะอ้างอิงวัตถุเดียวกัน


5
ใช่var arr1 = Enumerable.Repeat(new object(), 10).ToArray();คุณได้รับ 10 การอ้างอิงไปยังวัตถุเดียวกัน ในการสร้างวัตถุ 10 แบบที่แตกต่างคุณสามารถใช้var arr2 = Enumerable.Repeat(/* dummy: */ false, 10).Select(x => new object()).ToArray();หรือคล้ายกันได้
Jeppe Stig Nielsen

20
var contacts = new[]
{
    new 
    {
        Name = " Eugene Zabokritski",
        PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }
    },
    new 
    {
        Name = " Hanying Feng",
        PhoneNumbers = new[] { "650-555-0199" }
    }
};

คุณควรใช้โครงสร้างนี้อย่างไร มันเหมือนพจนานุกรมหรือไม่?
R. Navega

1
@ R.Navega มันเป็นอาร์เรย์ธรรมดา :)
22419

17

ในกรณีที่คุณต้องการเริ่มต้นอาร์เรย์คงที่ขององค์ประกอบที่เท่าเทียมกัน (ไม่ใช่ - nullหรืออื่น ๆdefault) ก่อนกำหนดให้ใช้สิ่งนี้:

var array = Enumerable.Repeat(string.Empty, 37).ToArray();

นอกจากนี้โปรดมีส่วนร่วมในเรื่องนี้การอภิปราย


13

ตัวอย่างการสร้างอาเรย์ของคลาสแบบกำหนดเอง

ด้านล่างเป็นคำจำกัดความของคลาส

public class DummyUser
{
    public string email { get; set; }
    public string language { get; set; }
}

นี่คือวิธีที่คุณสามารถเริ่มต้นอาร์เรย์:

private DummyUser[] arrDummyUser = new DummyUser[]
{
    new DummyUser{
       email = "abc.xyz@email.com",
       language = "English"
    },
    new DummyUser{
       email = "def@email.com",
       language = "Spanish"
    }
};


6
int[] array = new int[4]; 
array[0] = 10;
array[1] = 20;
array[2] = 30;

หรือ

string[] week = new string[] {"Sunday","Monday","Tuesday"};

หรือ

string[] array = { "Sunday" , "Monday" };

และในอาร์เรย์หลายมิติ

    Dim i, j As Integer
    Dim strArr(1, 2) As String

    strArr(0, 0) = "First (0,0)"
    strArr(0, 1) = "Second (0,1)"

    strArr(1, 0) = "Third (1,0)"
    strArr(1, 1) = "Fourth (1,1)"

5
สวัสดีบล็อกตัวอย่างสุดท้ายดูเหมือนจะเป็น Visual Basic คำถามจะถามตัวอย่าง c #
Alex KeySmith


2

อีกวิธีในการสร้างและเริ่มต้นอาร์เรย์ของวัตถุ นี่คล้ายกับตัวอย่างที่ @Amol โพสต์ไว้ด้านบนยกเว้นอันนี้ใช้คอนสตรัคเตอร์ เส้นประที่มีความแตกต่างหลากหลายฉันไม่สามารถต้านทานได้

IUser[] userArray = new IUser[]
{
    new DummyUser("abc@cde.edu", "Gibberish"),
    new SmartyUser("pga@lna.it", "Italian", "Engineer")
};

คลาสสำหรับบริบท:

interface IUser
{
    string EMail { get; }       // immutable, so get only an no set
    string Language { get; }
}

public class DummyUser : IUser
{
    public DummyUser(string email, string language)
    {
        m_email = email;
        m_language = language;
    }

    private string m_email;
    public string EMail
    {
        get { return m_email; }
    }

    private string m_language;
    public string Language
    {
        get { return m_language; }
    }
}

public class SmartyUser : IUser
{
    public SmartyUser(string email, string language, string occupation)
    {
        m_email = email;
        m_language = language;
        m_occupation = occupation;
    }

    private string m_email;
    public string EMail
    {
        get { return m_email; }
    }

    private string m_language;
    public string Language
    {
        get { return m_language; }
    }

    private string m_occupation;
}

1

สำหรับชั้นเรียนด้านล่าง:

public class Page
{

    private string data;

    public Page()
    {
    }

    public Page(string data)
    {
        this.Data = data;
    }

    public string Data
    {
        get
        {
            return this.data;
        }
        set
        {
            this.data = value;
        }
    }
}

คุณสามารถเริ่มต้นอาร์เรย์ของวัตถุด้านบนได้ดังนี้

Pages = new Page[] { new Page("a string") };

หวังว่านี่จะช่วยได้


0

คุณยังสามารถสร้างอาร์เรย์แบบไดนามิกเช่นคุณสามารถถามขนาดของอาร์เรย์จากผู้ใช้ก่อนสร้าง

Console.Write("Enter size of array");
int n = Convert.ToInt16(Console.ReadLine());

int[] dynamicSizedArray= new int[n]; // Here we have created an array of size n
Console.WriteLine("Input Elements");
for(int i=0;i<n;i++)
{
     dynamicSizedArray[i] = Convert.ToInt32(Console.ReadLine());
}

Console.WriteLine("Elements of array are :");
foreach (int i in dynamicSizedArray)
{
    Console.WriteLine(i);
}
Console.ReadKey();

0

วิธีแก้ปัญหาเล็กน้อยด้วยการแสดงออก โปรดทราบว่าด้วย NewArrayInit คุณสามารถสร้างอาเรย์แบบหนึ่งมิติได้

NewArrayExpression expr = Expression.NewArrayInit(typeof(int), new[] { Expression.Constant(2), Expression.Constant(3) });
int[] array = Expression.Lambda<Func<int[]>>(expr).Compile()(); // compile and call callback

0

เพียงแค่ทราบ

อาร์เรย์ต่อไปนี้:

string[] array = new string[2];
string[] array2 = new string[] { "A", "B" };
string[] array3 = { "A" , "B" };
string[] array4 = new[] { "A", "B" };

จะถูกรวบรวมไปที่:

string[] array = new string[2];
string[] array2 = new string[]
{
   "A",
   "B"
};
string[] array3 = new string[]
{
   "A",
   "B"
};
string[] array4 = new string[]
{
   "A",
   "B"
};
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.