Console.WriteLine () dan kebutuhan akan argumen yang berlebihan?

87

Saya sedang menjelajahi dokumentasi dan melihat bahwa Console.WriteLine()metode ini memiliki beberapa kelebihan beban. Khususnya, rasa ingin tahu dan sebagian kebingungan saya berkaitan dengan ini:

public static void WriteLine(string format, params object[] arg);
public static void WriteLine(string format, object arg0);
public static void WriteLine(string format, object arg0, object arg1);
public static void WriteLine(string format, object arg0, object arg1, object arg2);
public static void WriteLine(string format, object arg0, object arg1, object arg2, object arg3);

Sepertinya berlebihan. Apa kebutuhan dari empat kelebihan beban lainnya di atas yang pertama? Metode pertama mampu melakukan segala sesuatu yang dapat dilakukan metode lain. Apakah ada masalah kinerja yang mereka coba atasi dengan memberikan kelebihan beban tambahan, yang menangani hingga empat argumen (yang terakhir)? Apakah overhead melalui larik hingga empat argumen cukup besar untuk memenuhi kebutuhan kelebihan beban ini?

BK
sumber

Jawaban:

102

Secara umum, Anda benar bahwa kelebihan beban pertama sudah cukup untuk kelebihan beban lainnya. Ini tidak sepenuhnya benar karena paramskata kunci tidak dapat digunakan untuk kasus tidak langsung seperti metode group binding. Sebagai contoh

delegate void E(string format, object o1);
E e = Console.WriteLine;

The paramsberlebihan tidak akan memuaskan kasus ini, itu hanya akan bekerja ketika kelebihan tertentu hadir

public static void WriteLine(string format, object arg0);

Itu kasus yang cukup esoteris. Alasan yang lebih penting adalah sebagai berikut

  1. Tidak semua bahasa CLI diperlukan untuk mendukung paramskata kunci tersebut. Memiliki kelebihan beban mengurangi beban pada bahasa tersebut dengan menghilangkan kebutuhan untuk membuat array secara manual untuk panggilan WriteLine` sederhana
  2. Performa. Memanggil paramskelebihan beban memaksa pemanggil untuk mengalokasikan sebuah array, meskipun itu dilakukan secara implisit oleh kompilator. Alokasi murah di .Net tetapi tidak gratis. Hal-hal kecil seperti ini bertambah dengan cepat terutama pada metode yang biasa disebut seperti Console.WriteLine. Memiliki kelebihan beban lainnya memungkinkan kasus umum menghindari alokasi ini
JaredPar
sumber
1
Saya telah memikirkan kasus grup metode dalam jawaban saya tetapi saya cukup yakin konversi grup metode tidak diperkenalkan sampai C # 2.0 sedangkan WriteLine overloads tanggal kembali ke setidaknya 1.1.
jaket
@jaket Sintaks yang nyaman ditambahkan di C # 2.0. Tetapi hal yang sama berlaku jika Anda menggunakan eksplisit new E(Console.WriteLine)dalam C # 1.
CodesInChaos
5
Apakah alokasi array bahkan terlihat dengan seberapa lambat Console.WriteLine?
Bryan Boettcher
3
@insta bukanlah kecepatan tetapi akumulasi alokasi yang menjadi masalah. GC murah bukan gratis dan dalam aplikasi yang rumit GC sering kali menjadi faktor performa yang mendominasi. Menghentikan sumber umum alokasi yang tidak perlu penting untuk kinerja
JaredPar
38

Kelebihan beban adalah untuk kenyamanan program C ++ / CLI di mana kata kunci params tidak ada.

jaket
sumber
1
Itu jawaban yang bagus, untuk pertanyaan bagus, IMHO juga.
Uwe Keim
1
Ahh ... itu sangat masuk akal. Saya malu, C ++ adalah bahasa pertama saya. :)
BK
3
dasar-dasarnya dimulai dari bahasa pertama, jawaban pintar sobat
dbw
4

Saya pikir kalian semua lupa bahwa params diperkenalkan di C # 2.0. Oleh karena itu, kelebihan juga ada dari .NET 1.1, jika kata kunci params tidak.

Alan
sumber
jaket menyebutkan itu.
BK
Baca komentarnya atas jawaban JaredPar. Itulah salah satu alasan mengapa dia tidak memasukkan penjelasan param dalam jawabannya.
BK
@ Noobacode, memang benar dia melakukannya tetapi disimpulkan (seperti cara saya membacanya). Saya memberikan suara positif (untuk sesedikit itu nilainya) kepada Alan di sini karena dia menyatakannya dengan cara yang lebih langsung.
Frank V
1
Dari tautan ini params kata kunci ada di .Net 1.1 juga
Sriram Sakthivel
1

Menurut saya pertanyaan yang diajukan sudah mendapat jawaban yang baik dan jelas dari JaredPar dan jaket tapi ada satu hal yang menurut saya bisa relevan juga,

Menurut saya kemudahan penggunaan dan kebebasan bagi pengguna untuk menggunakan salah satu fungsi di atas sesuai dengan kebutuhan yang ada, dengan demikian, kebutuhan jauh lebih nyaman daripada memaksakan mereka untuk membuat array, ketika mereka benar-benar tidak membutuhkannya.

Saya juga berpikir tentang masa lalu ketika saya mulai mempelajari C # Saya hampir tidak menggunakan array dan menggunakan array adalah tugas yang rumit bagi saya, untuk menetapkannya dan kemudian menginisialisasi mereka dengan nilai yang tepat benar-benar rumit dan memakan waktu juga ...

dbw
sumber
3
Tapi idenya paramsadalah agar Anda bisa meneruskan array, atau secara eksplisit menulis semua argumen. metode seperti void do(params object[])bisa disebut dengan do(new object[] {"some", "stuff"}atau do("some", "stuff"). Saya tidak berpikir maksud Anda benar-benar berlaku di sini.
Kroltan
2
@Kroltan tetapi dapatkah Anda memberi tahu berapa banyak pemula yang benar-benar tahu artinya paramsdan mereka tahu jika paramsada, maka Anda dapat meneruskan variabel sebagai dipisahkan koma.
dbw
1
@Kroltan Saya juga tidak tahu kegunaannya paramsbisa seperti ini untuk waktu yang lama dan di bagian bantuan ditampilkan di Visual Studion jika saya mendapatkan array []sebagai argumen saya akan berpikir sama untuk menyediakan array sebagai argumen ....
dbw
-3

Ini tidak benar-benar untuk masalah kinerja seperti itu. Namun, meningkatkan kegunaan adalah alasan yang sah di baliknya.

Kode di bawah ini, akan memberi Anda sedikit wawasan.

public class TipCalculator {
    private const double tipRate = 0.18;
    public static int Main(string[] args) {
        double billTotal;
        if (args.Length == 0) {
            Console.WriteLine("usage: TIPCALC total");
            return 1;
        }
        else {
            try {
                billTotal = Double.Parse(args[0]);
            }
            catch(FormatException) {
                Console.WriteLine("usage: TIPCALC total");
                return 1;
            }
            double tip = billTotal * tipRate;
            Console.WriteLine();
            Console.WriteLine("Bill total:\t{0,8:c}", billTotal);
            Console.WriteLine("Tip total/rate:\t{0,8:c} ({1:p1})", tip, tipRate);
            Console.WriteLine(("").PadRight(24, '-'));
            Console.WriteLine("Grand total:\t{0,8:c}", billTotal + tip);
            return 0;
        }
    }
}

Silakan merujuk ke tautan: http://msdn.microsoft.com/en-us/library/aa324774(v=vs.71).aspx untuk informasi lebih lanjut.

Deepak Sharma
sumber
9
Bagaimana cara meningkatkan kegunaan? Metode pertama dapat melakukan hal yang sama persis dengan empat metode lainnya. Anda merujuk saya ke dokumentasi, sementara saya hanya mengatakan bahwa saya sedang melihat-lihat dokumentasi. Saya tahu untuk apa metode itu digunakan dan bagaimana cara menggunakannya (saya tidak baru mengenal C # dengan cara apa pun). Tetapi mengapa ada kebutuhan kelebihan beban tambahan di atas yang pertama.
BK
Saya pikir apa yang dia maksud adalah, karena hanya melewatkan satu parameter, tidak ada gunanya membuat array untuk menahannya, dan meneruskannya ke metode - mengapa tidak meneruskan satu parameter saja? Itulah alasan saya melakukan hal seperti itu
KingTravisG
@ SCassidy1986: Anda tidak membuat array ketika itu adalah metode params, kecuali Anda menginginkannya. Kompiler akan membuatnya secara otomatis. Itulah inti dari kedua param dan pertanyaan ini.
Magus