C # bir yöntem grubu nedir?


351

Sık sık "yöntem grubu '' dize '' gibi durumlarda dönüştürebilirsiniz" gibi bir hatayla karşılaştım:

var list = new List<string>();
// ... snip
list.Add(someObject.ToString);

Tabii ki son satırda bir yazım hatası vardı çünkü sonradan çağırma parantezlerini unuttum ToString. Doğru form:

var list = new List<string>();
// ... snip
list.Add(someObject.ToString()); // <- notice the parentheses

Ancak bir yöntem grubunun ne olduğunu merak etmeye başladım. Google ne bir yardım ne de MSDN .


62
C # 3.0 spesifikasyonunun Bölüm 7.1, "yöntem grubu" nu tanımlar.
Eric Lippert

2
Bir yöntemi çağırırken köşeli parantezleri kaçırdığınız için bu hatayı şimdi okudum .
niico

2
Örneğin, uygun bir delege türünün bir listesi var list = new List<Func<string>>();olsaydı, yöntem grubu kullanılabilir ve list.Add(someObject.ToString);işe yarardı.
Jeppe Stig Nielsen

Yanıtlar:


332

Bir yöntem olup grubu, bir adıdır dizi yöntemler (sadece biri olabilir) - yani teorik olarak ToStringyöntem, birden fazla aşırı yüklenmeleri (artı herhangi bir uzantısı yöntemleri) sahip olabilir: ToString(), ToString(string format)vb - bu nedenle ToStringkendi başına bir "yöntemi grubu".

Genellikle aşırı yük çözünürlüğü kullanarak bir yöntem grubunu (yazılan) bir temsilciye dönüştürebilir - ancak bir dizeye vb. mantıklı değil.

Parantez ekledikten sonra tekrar; aşırı yük çözünürlüğü devreye girer ve kesin olarak bir yöntem çağrısı belirlediniz.


6
Bir yöntem grubunun tipik kullanımları nelerdir? (Anlıyorum) aynı ada sahip olduğundan parametre sayısı ve / veya türleri farklı olacaktır. Bu nedenle, grubu kullanarak yöntem grubundan birden fazla yöntemi çağıramazsınız.
Andrei Rînea

32
"Yöntem adının ne olduğunu biliyorum, ama imzayı bilmiyorum" için derleyici bir terimdir; çalışma zamanında varlığı yoktur. AFAIK, bir yöntem grubunun tek başına (parantez vb.) Tek kullanımı delege yapımı sırasındadır.
Marc Gravell

20
ECMA 334v4 §14.1: Bir yöntem grubu, bir çağırma ifadesinde (§14.5.5) kullanılabilir, bir temsilci oluşturma ifadesinde (§14.5.10.3) kullanılabilir veya örtük olarak uyumlu bir temsilci türüne dönüştürülebilir. Başka herhangi bir bağlamda, yöntem grubu olarak sınıflandırılan bir ifade derleme zamanı hatasına neden olur.
Marc Gravell

1
Yöntem grupları için kovaryans ve karşıtlık desteği, yöntem imzalarının temsilci türleriyle eşleştirilmesine olanak tanır. Bu, delegelere yalnızca eşleşen imzaları olan yöntemleri değil, aynı zamanda daha türetilmiş türleri (kovaryans) döndüren veya delege türünde belirtilenden daha az türetilmiş türleri (karşıtlık) olan parametreleri kabul eden yöntemleri atamanızı sağlar. Daha fazla bilgi için, bkz. Temsilcilerdeki Sapma (C #) ve Temsilcilerdeki Sapma (C #).
user2211290

162

Ayrıca, LINQ kullanıyorsanız, görünüşe göre böyle bir şey yapabilirsiniz myList.Select(methodGroup).

Yani, örneğin:

private string DoSomethingToMyString(string input)
{
    // blah
}

Bunun için kullanılacak değişkeni açıkça belirtmek yerine:

public List<string> GetStringStuff()
{
    return something.getStringsFromSomewhere.Select(str => DoSomethingToMyString(str));
}

Ben sadece var adını atlayabilirsiniz:

public List<string> GetStringStuff()
{
    return something.getStringsFromSomewhere.Select(DoSomethingToMyString);
}

112
MeSharper önerisi beni yöntem grubunu aramaya iten şeydi. ReSharper, linq ifadelerimden birine bunu yaptı.
a_hardin

50
@a_hardin: ReSharper FTW! Resharper sayesinde LINQ hakkında çok şey öğrendim.
Jason Down

3
"Daha açık" sürüm yalnızca temelde işe yaramaz bir sargı yöntemi yapmaktır. Anonim sarma yöntemi ve DoSomethingToMyString, bir dize alır ve bir dize döndürür. "Str => [...] (str)" karakterleri sadece derleyicinin umarız optimize ettiği bir şey değildir.
Grault

6
Derleyici hiçbir şeyi optimize etmez. ILDASM kullanarak, açık sürümün anonim bir yöntem (lambda uygulaması) oluşturduğunu ve Select () öğesine ilettiğini görürsünüz. Örtük sürüm DoSomethingToMyString öğesini doğrudan iletir.
Rolf

14
Bana hatırlatıyor return flag == true ? true : false(facepalm).
ErikE

24

Bir yöntem grubunu temsilci olarak atayabilirsiniz.

Delege imzası gruptan 1 yöntem seçer.

Bu örnek ToString(), bir string parametresi alan aşırı yüklenmeyi seçer :

Func<string,string> fn = 123.ToString;
Console.WriteLine(fn("00000000"));

Bu örnek, ToString()parametre almayan aşırı yüklenmeyi seçer :

Func<string> fn = 123.ToString;
Console.WriteLine(fn());

21

MSDN aramanızdaki ilk sonuç şunları söyledi:

Yöntem grubu, çağrılacak bir yöntemi veya çağrılacak belirli bir yöntemin seçileceği aşırı yüklenmiş yöntemler kümesini tanımlar

benim anlayışım temelde çünkü sadece yazdığınızda someInteger.ToString,

Int32.ToString(IFormatProvider) 

ya da şunları ifade edebilir:

Int32.ToString()

bu yüzden buna yöntem grubu denir.


18

ToStringFonksiyonu çok sayıda aşırı yükleme vardır - yöntem grubu bu işlev için farklı aşırı oluşan grubu olacaktır.


2
Evet ve önemli olan bir yöntem grubunun derleme zamanı yapısı olmasıdır. Derleyici, ileti grubunun kullanıldığı bağlama göre bir yöntem aşırı yüklenmesi seçer. Örneğin: "var x = Foo;" (burada Foo bir yöntem grubudur), yalnızca bir aşırı yük olsa bile derleyici bunu reddeder.
Rolf
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.