Func açıklaması


90

Birisinin ne Func<int, string>olduğunu ve nasıl kullanıldığını bazı net örneklerle açıklayıp açıklayamayacağını merak ediyordum .

Yanıtlar:


146

Genel olarak delegelere aşina mısınız? Temsilciler ve olaylar hakkında , olmasa da yardımcı olabilecek bir sayfam var , ancak daha çok ikisi arasındaki farkları açıklamaya yönelik.

Func<T, TResult>sadece genel bir temsilcidir - herhangi bir özel durumda, tür parametrelerini ( Tve TResult) bildirimdeki karşılık gelen tür argümanlarıyla ( intve string) değiştirerek bunun ne anlama geldiğini hesaplayın. Karışıklığı önlemek için de adını değiştirdim:

string ExpandedFunc(int x)

Başka bir deyişle, Func<int, string>bir intbağımsız değişken alan ve a döndüren bir işlevi temsil eden bir temsilcidir string.

Func<T, TResult>LINQ'da hem tahminler hem de tahminler için sıklıkla kullanılır (ikinci durumda TResulther zaman kullanılır bool). Örneğin, Func<int, string>bir tamsayı dizisini bir dizge dizisine yansıtmak için a kullanabilirsiniz . Lambda ifadeleri genellikle LINQ'de ilgili temsilcileri oluşturmak için kullanılır:

Func<int, string> projection = x => "Value=" + x;
int[] values = { 3, 7, 10 };
var strings = values.Select(projection);

foreach (string s in strings)
{
    Console.WriteLine(s);
}

Sonuç:

Value=3
Value=7
Value=10

3
"Başka bir deyişle, bu, bir int bağımsız değişkenini alıp bir dizge döndüren bir işlevi temsil eden bir temsilci." Sadece başkalarının kafasını karıştırmamak için burada Func <int, string> hakkında konuştuğunuzu ve Func <T, TResult> 'dan bahsetmediğinizi açıklığa kavuşturacağım. Genel türleri ve delegeleri anlıyorsanız açıktır, ancak anlamayanlar için kan'ın int argüman alan ve bir dize döndüren bir işleve delege ettiği Func <int, string> dir.
The real napster

Daha sonra bir PC'ye geri döndüğümde netleşecek.
Jon Skeet

2
Bunun aslında MSDN'nin açıklaması ve örneği kadar net olmadığını düşünüyorum. Ayrıca, son tür parametresinin dönüş türü hakkında bilgi eklemeniz gerektiğini düşünüyorum - Func <int, int, string> 'in string döndürdüğünü ve 2 inç aldığını açıklığa kavuşturmak. Bu netleşmeye yardımcı olur. Kişisel bir şey değil - sadece yeterince açık olduğunu düşünmedim.
TheSoftwareJedi

11
Öyleyse, en sevdiğiniz kadar yararlı olmadığını düşündüğünüz her yanıtı olumsuz mu vereceksiniz? Bu yanıt aktif olarak yardımcı olmuyor mu , sence? Bir şeylere birden fazla şekilde bakmanın kötü bir fikir olmayabileceğini düşünüyor musunuz?
Jon Skeet

8
@TheSoftwareJedi: Hayır, tabii ki, hiçbir neden şahsen downvote almak - Eğer gerçeği yaptım tam o sırada Cumartesi günü kişisel nedenlerden ötürü downvote ve oldu biz uygun davranışı hakkında e-posta üzerinde uzun bir tartışmayı yapmak been sonra bu konuya girmesi olduğu tamamen bu tesadüf değil mi?
Jon Skeet

40

A Func<int, string>girişleri yer ve dizeleri döndürür. Öyleyse, ints'i yer ve dizeleri döndüren nedir? Buna ne dersin ...

public string IntAsString( int i )
{
  return i.ToString();
}

Orada, ints yiyen ve dizeleri döndüren bir işlev oluşturdum. Nasıl kullanırım?

var lst = new List<int>() { 1, 2, 3, 4, 5 };
string str = String.Empty;

foreach( int i in lst )
{
  str += IntAsString(i);
}

// str will be "12345"

Çok seksi değil, biliyorum ama birçok numaranın dayandığı basit fikir bu. Şimdi bunun yerine bir Func kullanalım.

Func<int, string> fnc = IntAsString;

foreach (int i in lst)
{
  str += fnc(i);
}

// str will be "1234512345" assuming we have same str as before

Her üyede IntAsString'i çağırmak yerine, ona fnc adında bir referans oluşturdum (yöntemlere yapılan bu referanslara delegeler denir ) ve onu kullandım. (Unutmayın fnc girişleri yedi ve dizeler döndürür).

Bu örnek çok seksi değil, ancak göreceğiniz bir sürü zekice şey, işlevler, delegeler ve uzatma yöntemlerinin basit fikrine dayanıyor .

Bu şeyde gördüğüm en iyi primerlerden biri burada . Çok daha gerçek örnekleri var. :)


@Therealnapster ben de beğendim ama ismini daha çok seviyorum.
BKSpurgeon

28

Birini intparametre olarak alan ve bir tür değeri döndüren bir temsilcidir string.

İşte kullanımına bir örnek:

using System;

class Program
{
    static void Main()
    {
        Func<Int32, String> func = bar;

        // now I have a delegate which 
        // I can invoke or pass to other
        // methods.
        func(1);
    }

    static String bar(Int32 value)
    {
        return value.ToString();
    }
}

3
Teşekkürler Andrew. Bar (1) yerine func (1) yazmak mı istediniz?
zSynopsis

1

Func<int, string>int değer parametresini kabul eder ve bir dize değeri döndürür. Ek bir destekleme yönteminin gereksiz olduğu bir örneği burada bulabilirsiniz.

Func<int, string> GetDogMessage = dogAge =>
        {
            if (dogAge < 3) return "You have a puppy!";
            if (dogAge < 7) return "Strong adult dog!";

            return "Age is catching up with the dog!";
        };

string youngDogMessage = GetDogMessage(2);

NOT: Func'daki son nesne türü (yani bu örnekte "dize"), işlevlerin dönüş türüdür (yani ilkellerle sınırlı değildir, ancak herhangi bir nesneyle). Bu nedenle, Func<int, bool, float>int ve bool değer parametrelerini kabul eder ve bir float değeri döndürür.

Func<int, bool, float> WorthlessFunc = (intValue, boolValue) =>
        {
            if(intValue > 100 && boolValue) return 100;

            return 1;
        };
float willReturn1 = WorthlessFunc(21, false);
float willReturn100 = WorthlessFunc(1000, true);

HTH

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.