Func

2009-08-15 22 views
134

parametresiyle Outc fonksiyon parametresi Func olarak çıkış yapabilir miyim?Func

public IList<Foo> FindForBar(string bar, out int count) { } 

// somewhere else 
public IList<T> Find(Func<string, int, List<T>> listFunction) { } 

Func orada derlemek etmeyecek şekilde dışarı bir tür ihtiyacı vardır ve çağıran listFunction bir int gerektirir ve bir out izin vermez.

bunu yapmanın bir yolu var mı?

cevap

192

ref ve out türü parametre tanımının parçası olmayan dahili Func delege ref ve out argümanları geçmek. Tabii ki, size isterseniz kendi temsilci ilan edebilir:

delegate V MyDelegate<T,U,V>(T input, out U output); 
+13

Benim gibi başka birinin kafası karışmışsa, yerleşik kişiler gibi "Func" temsilcisini çağırmak için * seçeneğiniz yok ... – Dunc

+0

@Dunc - Düzeltildi. Yorumunuz için değil, gerçekten kafam karışmış olurdu. –

+5

C# 4 (2010) ve daha sonra (cevabınızı yazdığınızda serbest bırakılmadı), T'yi kontravaryant olarak işaretlemek mümkündür ve "V" kovaryant olarak. Bununla birlikte, "U" türünde bir parametre ('output') *** tarafından *** aktarıldığından, 'U' birlikte veya kontravaryant olarak işaretlenemez ve" değişmez "olarak kalmalıdır. Yani, genel delege V MyDelegate'i T, U, V> (T girişi, U çıkışı) olarak düşünün; C# 4 veya daha sonra kullanırsanız. –

19

Neden sonuçları kapsüllemek için bir sınıf oluşturmuyorsunuz?

public class Result 
{ 
    public IList<Foo> List { get; set; } 
    public Int32 Count { get; set; } 
} 
0

Sen FindForBar denilen doğru arayüzü ve maruz kalan bir lambda/temsilci/fonksiyon/yönteminde bunu sarabilirdiniz, ama gerek diye, FindForBar, gerekçe olarak bir takım parametre olarak saymak şüpheleniyorsanız Bu bilgiyi attığınızdan emin olun, tamam/güvenli/arzu edilebilir/doğru sonuçlara sahip olsaydınız (doğrudan FindForBar'da geçebilseniz bile bundan emin olmanız gerekir). Eğer kullanamaması için

9

delegenin (ya da bu konuda Action) ait Func ailesi

//.NET 4 and above 
public delegate TResult Func<out TResult>() 
public delegate TResult Func<in T, out TResult>(T obj) 

//.NET 3.5 
public delegate TResult Func<T1, T2, TResult>(T1 obj1, T2 obj2) 
public delegate TResult Func<T1, T2, T3, TResult>(T1 obj1, T2 obj2, T3 obj3) 

vb Delegeler gibi ilan basit temsilci türleri başka bir şey değildir böylece/ref parametreler olabilir, bu durumda sizin için diğer cevaplar gibi kendi kendine özel bir uygulama meselesidir. Microsoft'un bunu varsayılan olarak neden paketlemediğine göre, gerektirecek çok sayıda bileşimi düşünün. Sadece iki parametre için

delegate TResult Func<T1, T2, TResult>(T1 obj1, T2 obj2) 
delegate TResult Func<T1, T2, TResult>(out T1 obj1, T2 obj2) 
delegate TResult Func<T1, T2, TResult>(T1 obj1, out T2 obj2) 
delegate TResult Func<T1, T2, TResult>(out T1 obj1, out T2 obj2) 

. ref'a bile dokunmadık. Aslında geliştiriciler için hantal ve kafa karıştırıcı olurdu.

+1

C# işlevinin aşırı yüklenmesinin "temsilci TResult Func (T1 obj, T2 obj)" ve "temsilci TResult Func (dışarıda T1 obj, T2 obj)" arasında ayrım yapamayacağını unutmayın. Bu nedenle, aşırı yüklenme sembolü adının yanı sıra, Microsoft'un bu Func 'aşırı yüklemelerini neden ekleyemediğinin bir başka nedeni de var. –