Mengapa C # mengizinkan {} blok kode tanpa pernyataan sebelumnya?

86

Mengapa C # memungkinkan blok kode tanpa pernyataan sebelumnya (misalnya if, else, for, while)?

void Main()
{
    {   // any sense in this?
        Console.Write("foo");
    }
}
Seldon
sumber
70
Apakah ada alasan untuk tidak melakukannya ?
Jamiec
30
Tetapi karena jawaban menunjukkan itu memiliki lebih banyak makna daripada hanya "tidak sakit, jadi biarkan saja". Ini adalah tujuan mengajukan pertanyaan seperti itu.
Seldon
8
Pertanyaan +1 kedengarannya cukup polos, tetapi jawaban benar-benar mengajari saya sesuatu yang berharga
Nicolas78
7
@ Akash: Tanpa bertanya mengapa, kami tidak akan pernah menjadi lebih baik.
richard
7
@ Akash: Sepertinya itu adalah sikap elitis yang tinggi. Orang selalu memiliki pertanyaan, dan jika tidak ada alasan untuk bertanya mengapa, maka tidak ada gunanya memiliki SO. Situs ini bukan untuk meminta orang memecahkan masalah langsung kita (meskipun itu benar-benar terjadi), tetapi untuk menyediakan gudang pertanyaan dan jawaban yang akan membantu kita semua menjadi pemrogram yang lebih baik. JADI untuk menanyakan MENGAPA! :-)
richard

Jawaban:

90

Dalam konteks yang Anda berikan, tidak ada artinya. Menulis string konstan ke konsol akan bekerja dengan cara yang sama di manapun dalam aliran program. 1

Sebaliknya, Anda biasanya menggunakannya untuk membatasi cakupan beberapa variabel lokal. Ini dijelaskan lebih lanjut di sini dan di sini . Lihatlah jawaban João Angelo dan jawaban Chris Wallis untuk contoh singkat. Saya percaya hal yang sama berlaku untuk beberapa bahasa lain dengan sintaks gaya-C juga, meskipun mereka tidak relevan dengan pertanyaan ini.


1 Kecuali, tentu saja, Anda memutuskan untuk mencoba menjadi lucu dan membuat Consolekelas Anda sendiri , dengan Write()metode yang melakukan sesuatu yang sama sekali tidak terduga.

BoltClock
sumber
24
Re: bahasa lain: biasanya, tetapi tidak selalu. JavaScript adalah pengecualian penting; mendeklarasikan variabel lokal dalam blok tertentu tidak mencakup variabel ke blok.
Eric Lippert
@EricLippert: Dalam C #, apakah mendeklarasikan variabel di dalam blok menyebabkan variabel dicakup dari perspektif run-time? Dari apa yang saya tahu, masa pakai variabel seringkali tidak dibatasi oleh blok pelingkupan, sebuah fakta yang dapat diamati dalam proyek bahasa campuran jika hal pertama yang dilakukan dengan variabel dalam satu lingkaran adalah meneruskannya sebagai outparameter ke implementasi antarmuka tertulis dalam bahasa lain, dan implementasi itu membaca variabel sebelum menulisnya.
supercat
Dan di C ++, karena RAII bukan GC, ini jauh lebih berguna.
Deduplicator
Di C ++, ini bertindak seperti blok coba / tangkap, sehingga variabel dan kelas yang dideklarasikan dalam cakupan itu keluar dari tumpukan saat Anda meninggalkan ruang lingkup itu. Ini membantu mencegah benturan nama dan mengurangi jejak memori fungsi. Ini juga menghapus variabel-variabel tersebut dari pelengkapan otomatis editor kode. Seringkali saya menemukan blok coba / tangkap lebih berguna.
Kit10
144

Itu { ... } memiliki setidaknya efek samping memperkenalkan lingkup baru untuk variabel lokal.

Saya cenderung menggunakannya dalam switchpernyataan untuk memberikan ruang lingkup yang berbeda untuk setiap kasus dan dengan cara ini memungkinkan saya untuk mendefinisikan variabel lokal dengan nama yang sama di lokasi terdekat yang memungkinkan penggunaannya dan juga menunjukkan bahwa mereka hanya valid pada tingkat kasus.

João Angelo
sumber
6
Jika Anda membutuhkan cakupan dalam kasus Anda, mereka terlalu besar! Metode Ekstrak.
Jay Bazuzi
20
@Jay Bazuzi, hanya karena saya ingin memiliki variabel lokal dengan nama yang sama di lebih dari satu kasus tidak berarti mereka harus berukuran besar. Anda baru saja mengambil kesimpulan besar ... :)
João Angelo
Selamat atas lencana Jawaban Hebat Anda! :)
BoltClock
1
@BoltClock, terima kasih, saya hanya perlu beberapa pertanyaan lagi {}untuk tetap mendapatkan lencana emas itu ... :)
João Angelo
56

Ini bukan merupakan fitur C # tetapi merupakan efek samping logis dari banyak bahasa sintaks C yang menggunakan tanda kurung kurawal untuk menentukan cakupan .

Dalam contoh Anda, tanda kurung kurawal tidak berpengaruh sama sekali, tetapi dalam kode berikut mereka menentukan cakupan, dan karenanya, visibilitas, variabel:

Ini diperbolehkan karena saya keluar dari ruang lingkup di blok pertama dan didefinisikan lagi di blok berikutnya:

{
    {
        int i = 0;
    }

    {
        int i = 0;
    }
}

Ini tidak diperbolehkan karena saya telah keluar dari ruang lingkup dan tidak lagi terlihat di ruang lingkup luar:

{
    {
        int i = 0;
    }

    i = 1;
}

Dan seterusnya dan seterusnya.

Chris Wallis
sumber
1
Saya telah membaca tentang perbedaan dalam nomenklatur braket dalam berbagai bahasa Inggris, tetapi dalam rasa apa yang {}dikenal sebagai tanda kurung?
BoltClock
Pertanyaan bagus! Saya kira seorang mentor saya menanamkannya di otak saya satu dekade lalu. Saya mungkin harus memanggil mereka 'kurung keriting' atau 'kawat gigi'. Masing-masing memiliki ... en.wikipedia.org/wiki/…
Chris Wallis
10
Dalam kosakata saya '(' = tanda kurung, '{' = brace, '[' = square brackets
pb.
Tunggu, saya akan menyebutnya kurung kurawal, dan Wikipedia menyertakan penamaan itu. Kamus Bahasa Inggris Oxford mendefinisikan penggunaan tanda kurung sebagai: One of two marks of the form [ ] or ( ), and in mathematical use also {}, used for enclosing a word or number of words, a portion of a mathematical formula, or the like, so as to separate it from the context; Dalam hal apa pun itu bukan tanda kurung, tetapi 'kurung kurawal' tampaknya OK.
dumbledad
IME, "kurung kurawal" dan "tanda kurung siku".
cp.engr
18

Saya anggap {}sebagai pernyataan yang bisa memuat beberapa pernyataan.

Pertimbangkan pernyataan if yang ada di luar ekspresi boolean diikuti dengan satu pernyataan. Ini akan berhasil:

if (true) Console.Write("FooBar");

Ini akan berhasil juga:

if (true)
{
  Console.Write("Foo");
  Console.Write("Bar");
}

Jika saya tidak salah ini disebut pernyataan blok.

Karena {}dapat berisi pernyataan lain, ia juga dapat berisi lainnya {}. Ruang lingkup variabel ditentukan oleh induknya {}(pernyataan blok).

Poin yang saya coba buat adalah itu {}hanya pernyataan, jadi tidak memerlukan jika atau apa pun ...

RBaarda
sumber
+1 Itulah tepatnya tanda kurung dalam bahasa gaya-C - yang disebut "pernyataan majemuk".
Michael Ekstrand
12

Aturan umum dalam bahasa sintaks C adalah "apa pun di antara keduanya { }harus diperlakukan sebagai pernyataan tunggal, dan dapat digunakan di mana pun satu pernyataan bisa":

  • Setelah if.
  • Setelah for, whileatau do.
  • Di mana saja dalam kode .

Untuk semua maksud dan tujuan, karena tata bahasa termasuk ini:

     <statement> :== <definition of valid statement> | "{" <statement-list> "}"
<statement-list> :== <statement> | <statement-list> <statement>

Artinya, "pernyataan dapat terdiri dari (berbagai hal) atau kurung kurawal buka, diikuti oleh daftar pernyataan (yang dapat mencakup satu atau lebih pernyataan), diikuti oleh tanda kurung kurawal". IE "sebuah { }blok dapat menggantikan pernyataan apa pun, di mana saja". Termasuk di tengah kode.

Tidak mengizinkan { }blok di mana pun sebuah pernyataan bisa pergi sebenarnya akan membuat definisi bahasa lebih kompleks .

Massimo
sumber
Seseorang baru saja menaikkan jawaban ini (setelah 9 tahun), yang sebenarnya bukan jawaban spesifik untuk pertanyaan ini, tetapi lebih merupakan diskusi umum. Mungkin sangat bagus telah digantikan oleh bahasa dan perpustakaan .. Tapi itu menyenangkan, terima kasih.
Massimo
1

Karena C ++ (dan java) mengizinkan blok kode tanpa pernyataan sebelumnya.

C ++ mengizinkan mereka karena C melakukannya.

Bisa dibilang semuanya bermuara pada fakta bahwa desain bahasa program AS (berbasis C) menang daripada desain bahasa program Eropa ( berbasis Modula-2 ).

(Pernyataan kontrol bertindak atas satu pernyataan, pernyataan dapat menjadi kelompok untuk membuat pernyataan baru)

Ian Ringrose
sumber
Apakah yang Anda maksud Module2, atau Modula2?
Richard Ev
Memang ini jawaban yang benar. Selanjutnya, saya hanya akan menjawab "Karena setiap bahasa komputer begitu."
Fattie
1
// if (a == b)
// if (a != b)
{
    // do something
}
pengguna202448
sumber
0

1 Karena ... Mempertahankan Scope Area pernyataan .. atau Fungsi, Ini sangat berguna untuk kode besar ..

{
    {
        // Here this 'i' is we can use for this scope only and out side of this scope we can't get this 'i' variable.

        int i = 0;
    }

    {
        int i = 0;
    }
}

masukkan deskripsi gambar di sini

Raj
sumber
0

Anda bertanya "mengapa" C # mengizinkan blok kode tanpa pernyataan sebelumnya. Pertanyaan "mengapa" juga dapat diartikan sebagai "apa manfaat yang mungkin didapat dari konstruksi ini?"

Secara pribadi, saya menggunakan blok kode tanpa pernyataan di C # di mana keterbacaan sangat ditingkatkan untuk pengembang lain, sambil mengingat bahwa blok kode membatasi ruang lingkup variabel lokal. Misalnya, pertimbangkan cuplikan kode berikut, yang jauh lebih mudah dibaca berkat blok kode tambahan:

OrgUnit world = new OrgUnit() { Name = "World" };
{
    OrgUnit europe = new OrgUnit() { Name = "Europe" };
    world.SubUnits.Add(europe);
    {
        OrgUnit germany = new OrgUnit() { Name = "Germany" };
        europe.SubUnits.Add(germany);

        //...etc.
    }
}
//...commit structure to DB here

Saya sadar bahwa ini dapat diselesaikan dengan lebih elegan dengan menggunakan metode untuk setiap tingkat struktur. Tapi sekali lagi, perlu diingat bahwa hal-hal seperti data sampel seeder biasanya harus cepat.

Jadi meskipun kode di atas dijalankan secara linier, struktur kode tersebut merepresentasikan struktur "dunia nyata" dari objek, sehingga memudahkan pengembang lain untuk memahami, memelihara, dan memperluas.

Marco
sumber