Out parametresi ile <T> işlevi


167

Out parametresine sahip bir yöntemi Func olarak iletebilir miyim?

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

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

Func, bir türe ihtiyaç duyar, bu nedenle dışarıda derlenmez ve listFunction çağrısı bir int gerektirir ve dışarıya izin vermez.

Bunu yapmanın bir yolu var mı?

Yanıtlar:


228

refve outtype parametresi tanımının bir parçası olmadığından, yerleşik Functemsilci'yi iletmek refve outbağımsız değişkenler için kullanamazsınız . Elbette, isterseniz kendi temsilcinizi beyan edebilirsiniz:

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

7
C # 4 (2010) ve sonrasında (cevabınızı yazdığınızda serbest bırakılmadı) Tkontravaryant ve Vkovaryant olarak işaretlemek mümkündür . Bununla birlikte, outputtürdeki bir parametre ( ) referansU olarak iletildiğinden , birlikte veya karşıt değişken olarak işaretlenemez ve "değişmez" olarak kalmalıdır. Bu yüzden C # 4 veya üstünü kullanıyorsanız düşünün . Upublic delegate V MyDelegate<in T, U, out V>(T input, out U output);
Jeppe Stig Nielsen


24

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

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

13

FuncDelegeler (veya ailesi Actionbu konuda) başka bir şey gibi ilan basit temsilci türleridir

//.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)

Bu şekilde delegeler dışarı / ref parametrelerine sahip olabilirler, bu nedenle sizin durumunuzda, diğer cevapların işaret ettiği gibi yalnızca kendiniz için özel bir uygulama söz konusudur. Microsoft'un bunu neden varsayılan olarak paketlemediğine gelince, gerektireceği çok sayıda kombinasyon düşünün.

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)

sadece iki parametre için. Dokunmadık bile ref. Aslında geliştiriciler için hantal ve kafa karıştırıcı olurdu.


2
C # işlevi aşırı yüklemesinin delegate TResult Func<T1, T2, TResult>(T1 obj, T2 obj)ve arasında ayrım yapamayacağını unutmayın delegate TResult Func<T1, T2, TResult>(out T1 obj, T2 obj). Bu nedenle, aşırı yük sayısının yanı sıra sembol adı, Microsoft'un bu aşırı yükleri ekleyememesinin başka bir nedenidir Func.
Kasper van den Berg

Birisi beni yukarıdaki delegelerle ilgili bir MSDN makalesine yönlendirebilir mi?
Su Llewellyn

@SuLlewellyn Orijinal msdn makalesini bulamadım, ancak şunu deneyebilirsiniz: docs.microsoft.com/en-us/dotnet/api/… , docs.microsoft.com/en-us/dotnet/api/…
nawfal

0

Doğru arabirimi açığa çıkaran ve FindForBar adlı lambda / delegate / işlev / yöntemle sarabilirsiniz, ancak FindForBar'ın bir neden olarak out parametresi olarak sayıldığından şüpheleniyorum, bu nedenle bu bilgileri atmaktan emin olmanız gerekir. ok / safe / arzu edilebilir / doğru sonuçlara ulaştı (doğrudan FindForBar'a geçebilseniz bile bundan emin olmanız gerekir).

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.