Console.WriteLine () ve bu kadar çok argüman aşırı yüklemesine ihtiyaç var mı?


87

Belgelere göz atıyordum ve Console.WriteLine()yöntemin birkaç aşırı yüklemesi olduğunu fark ettim . Özellikle merakım ve kısmi kafa karışıklığım bunlarla ilgili:

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);

Gereksiz görünüyor. İlkine ek olarak diğer dört aşırı yüklenmeye ne gerek var? İlk yöntem, diğer yöntemlerin yapabildiği her şeyi yapabilir. Dört bağımsız değişkeni (sonuncusu) işleyen ek aşırı yüklemeler sağlayarak üstesinden gelmeye çalıştıkları bir performans sorunu var mı? Bu aşırı yüklemelere olan ihtiyacı karşılayacak kadar büyük dört argümandan oluşan bir diziden geçmenin ek yükü var mı?

Yanıtlar:


102

Genel olarak, ilk aşırı yüklemenin diğer aşırı yüklemeler için yeterli olabileceği konusunda haklısınız. Bu kesinlikle doğru değildir, çünkü paramsanahtar kelime yöntem grubu bağlama gibi dolaylı durumlarda kullanılamaz. Örneğin

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

paramsBu özel aşırı yük varken aşırı yük sadece çalışacak, bu durumda tatmin olmaz

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

Yine de bu oldukça ezoterik bir durum. Daha önemli nedenler şunlardır

  1. paramsAnahtar kelimeyi desteklemek için her CLI dili gerekli değildir . Aşırı yüklemelere sahip olmak, basit bir WriteLine` çağrısı için manuel olarak bir dizi oluşturma ihtiyacını ortadan kaldırarak bu diller üzerindeki yükü azaltır.
  2. Verim. AranıyorparamsAşırı yüklemeyi çağıranı derleyici tarafından dolaylı olarak yapılsa bile bir dizi ayırmaya zorlar. .Net'te tahsisler ucuzdur ancak ücretsiz değildir. Bunun gibi küçük şeyler, özellikle yaygın olarak adlandırılan yöntemlerde hızla toplanır Console.WriteLine. Diğer aşırı yüklere sahip olmak, yaygın durumların bu tahsisattan kaçınmasına izin verir

1
Cevabımda yöntem grubu durumunu düşünmüştüm, ancak yöntem grubu dönüşümünün C # 2.0'a kadar tanıtılmadığından eminim, oysa WriteLine aşırı yüklemeleri en az 1.1'e kadar uzanıyor.
jaket

@jaket Uygun sözdizimi C # 2.0'a eklendi. Ancak, new E(Console.WriteLine)C # 1'de açık bir şekilde kullanırsanız aynı nokta geçerlidir .
CodesInChaos

5
Bir Console.WriteLine ne kadar yavaş olduğunda dizi tahsisi bile farkedilebilir mi?
Bryan Boettcher

3
@insta hız değil, sorun olan tahsislerin birikimi. GC ucuzdur, ücretsiz değildir ve karmaşık uygulamalarda GC genellikle baskın performans faktörüdür. Genel gereksiz tahsis kaynaklarının durdurulması performans için önemlidir
JaredPar

38

Aşırı yüklemeler, params anahtar kelimesinin bulunmadığı C ++ / CLI programlarının rahatlığı içindir.


1
Bu harika bir soruya harika bir cevap, IMHO da.
Uwe Keim

1
Ahh ... bu aslında çok mantıklı. Yazık bana, C ++ benim ilk dilimdi. :)
BK

3
temel bilgiler ilk dilden başlar, akıllı cevap dostum
dbw

4

Sanırım hepiniz parametrelerin C # 2.0'da tanıtıldığını unutuyorsunuz. Bu nedenle, params anahtar sözcüğü olmadığında .NET 1.1'den de aşırı yüklemeler vardır.


jaket bundan bahsetmişti.
BK

JaredPar'ın cevabı hakkındaki yorumunu okuyun. Cevabına param açıklamasını eklememesinin nedenlerinden biri budur.
BK

@Noobacode, yaptığı doğru ama çıkarsandı (nasıl okuduğum gibi). Burada Alan'a (bunun değeri ne kadar az olursa olsun) olumlu oy veriyorum çünkü bunu daha doğrudan bir malikanede belirtti.
Frank V

1
Bu bağlantıdan params anahtar kelimesi .Net 1.1'de de var
Sriram Sakthivel

1

Sanırım sorulan soru, JaredPar ve jaket'in iyi ve açıklayıcı yanıtlarına zaten sahip, ancak bir nokta da alakalı olabileceğini düşündüğüm

Bence kullanıcıların yukarıdaki fonksiyonlardan herhangi birini oradaki ihtiyaca göre kullanabilmeleri için kullanım kolaylığı ve özgürlüğü , bu şekilde, gerçekten ihtiyaç duymadıklarında bir dizi oluşturmaya zorlamaktan çok daha uygun bir ihtiyaç var.

C # öğrenmeye başladığım eski günleri de düşünüyorum, dizileri pek kullanmadım ve dizileri kullanmak benim için karmaşık bir görevdi, onu atamak ve sonra onları uygun değerlerle başlatmak gerçekten karmaşık ve zaman alıcıydı ...


3
Ancak fikir, paramsya bir diziyi iletebilmeniz ya da tüm argümanları açıkça yazabilmenizdir. gibi bir yöntem veya void do(params object[])ile çağrılabilir . Senin fikrinin burada tam olarak geçerli olduğunu sanmıyorum. do(new object[] {"some", "stuff"}do("some", "stuff")
Kroltan

2
@Kroltan, ancak kaç tane yeni başlayan kişinin anlamını gerçekten bildiğini söyleyebilir misiniz paramsve varsa params, o zaman değişkenleri virgülle ayrılmış olarak geçirebilirsiniz.
dbw

1
@Kroltan Ben de kullanımının paramsuzun süredir böyle olabileceğini bilmiyordum ve Visual Studion'da görüntülenen yardım bölümünde array []argüman olarak alırsam , argüman olarak dizi sağlamak için aynı şeyi düşüneceğim ....
dbw

-3

Bu gerçekten performans sorunu için geçerli değil. Ancak kullanılabilirliği artırmak bunun arkasında geçerli bir sebeptir.

Aşağıdaki kod size küçük bir fikir verecektir.

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;
        }
    }
}

Daha fazla bilgi için lütfen http://msdn.microsoft.com/en-us/library/aa324774(v=vs.71).aspx bağlantıya bakın .


9
Bu kullanılabilirliği nasıl artırır? İlk yöntem, diğer dördü ile tamamen aynı şeyi yapabilir. Belgelere baktığımı söylerken, sen beni belgelere yönlendiriyorsun. Bu yöntemin ne için kullanıldığını ve nasıl kullanılacağını biliyorum (C # konusunda hiçbir şekilde yeni değilim). Ama neden ilkine ek olarak ek aşırı yüklemelere ihtiyaç var?
BK

Sanırım onun kastettiği, sadece bir parametreyi geçirmek için, onu tutacak bir dizi yaratmanın ve onu yönteme geçirmenin bir anlamı olmadığı - neden sadece bir parametreyi geçmiyor? Böyle bir şey yapmamın nedeni bu olabilir
KingTravisG

@ SCassidy1986: Sen sen istemedikçe bu bir params yöntem olduğunda dizi yapmazlar. Derleyici otomatik olarak bir tane oluşturacaktır. Her iki parametrenin ve bu sorunun amacı budur.
Magus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.