Aracılığıyla paylaş


Lambda ifadeleri (C# Programlama Kılavuzu)

Lambda ifadesi temsilciler veya ifade ağaç türleri oluşturmak için kullanabileceğiniz anonim bir işlevdir.Lambda ifadeleri kullanarak, yerel işlevler argüman olarak iletilen veya döndürülen işlev çağrılarının değeri yazabilirsiniz.Lambda ifadeleri LINQ sorgu ifadeleri yazmak için özellikle yararlıdır.

Lambda ifadesi oluşturmak için giriş parametreleri (varsa) lambda işlecinin sol tarafındaki belirttiğiniz = >, ve diğer yüzüne ifade ve deyimin blok yerleştirin.Örneğin, lambda ifadesi x => x * x adlı bir parametre belirtir x ve değerini döndürür x kare içinde.Bu ifade aşağıdaki örnekte gösterildiği gibi bir temsilci türü atayabilirsiniz:

delegate int del(int i);
static void Main(string[] args)
{
    del myDelegate = x => x * x;
    int j = myDelegate(5); //j = 25
}

Bir ifade ağacı türü oluşturmak için:

using System.Linq.Expressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Expression<del> myET = x => x * x;
        }
    }
}

=> İşleç atama olarak aynı önceliğe sahiptir (=) ve sağa ilişkilendirilebilir.

Lambda yöntem temelli olarak kullanılan LINQ gibi standart sorgu işleci yöntemleri bağımsız değişkenler olarak sorgular Where.

Aranacak yöntemine temel sözdizimini kullandığınızda Where yönteminde Enumerable sınıf (gördüğünüzle LINQ nesnelere ve LINQ to XML) bir temsilci türü parametresi System.Func<T, TResult>.Lambda ifadesi bu temsilciyi oluşturmak için en uygun yoldur.Örneğin, aynı yöntemi çağırdığınızda System.Linq.Queryable sınıf (gördüğünüzle LINQ to SQL) sonra da parametre türü bir System.Linq.Expressions.Expression<Func> Func Func temsilcileri ile en çok on altı giriş parametreleri olduğu.Yine, lambda ifadesi ifade ağacı oluşturmak için bir çok kısa yoldur.Lambda izin Where aslında lambda oluşturulan nesne türü farklı olsa da benzer aramalar.

Önceki örnekte, temsilci imza bir örtülü olarak yazılan vardır giriş parametresi türü intve döndüren bir int.Ayrıca bir giriş parametresi olduğundan bu tür bir temsilciye lambda ifadesi dönüştürülebilir (x) ve derleyici örtülü olarak yazmak için dönüştürebilirsiniz bir dönüş değeri int.(Tür çıkarımı aşağıdaki bölümlerde daha ayrıntılı olarak açıklanmıştır.) 5 Bir girdi parametresini kullanarak temsilci çağrıldığında, 25 sonucunu döndürür.

Lambda sol tarafında izin verilmez olan veya olarak işleci.

Anonim yöntemler için geçerli olan tüm kısıtlamalar, lambda ifadeleri için de geçerlidir.Daha fazla bilgi için bkz. Adsýz yöntemler (C# Programlama Kılavuzu).

Lambda ifadesi

Sağ tarafta bir ifade ile lambda ifadesi olarak adlandırılan bir ifade lambda.Deyim lambda bolca oluşumunu içinde kullanılan İfade ağaçları (C# ve Visual Basic).Deyim lambda ifade sonucunu verir ve aşağıdaki temel biçimi alır:

(input parameters) => expression

Parantez içinde yalnızca bir giriş parametresi lambda varsa isteğe bağlıdır; Aksi takdirde bunlar gereklidir.İki veya daha fazla giriş parametreleri ayraç içinde virgülle ayrılır:

(x, y) => x == y

Bazen zor ya da olanaksız giriş türleri gerçekleştirip derleyici.Bu durumda, aşağıdaki örnekte gösterildiği gibi açıkça türlerini belirleyebilirsiniz:

(int x, string s) => s.Length > x

Boş ayraçları sıfır giriş parametrelerini belirtin:

() => SomeMethod()

Not önceki örnekte ifade lambda gövdesi yöntem çağrısı oluşabilir.Ancak, sql Server gibi başka bir etki alanındaki tüketilen ifade ağaçları oluşturuyorsanız yöntem çağrıları lambda ifadeleri kullanmamalısınız.Yöntem .NET ortak dil çalışma zamanı mantığının dışında hiçbir anlamı olmayacaktır.

Deyimi lambda

Deyimi lambda deyim ayraç içine bir deyim lambda benzer:

(input parameters) => {statement;}

Gövdesi deyimi lambda ifadeleri herhangi bir sayıda oluşabilir; Ancak, uygulamada vardır iki veya üç genellikle artık.

delegate void TestDelegate(string s);
…
TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); };
myDel("Hello");

Anonim yöntemler gibi deyimi lambda ifade ağaçları oluşturmak için kullanılamaz.

Zaman uyumsuz lambda

Lambda ifadeleri ve zaman uyumsuz işleme kullanarak birleştirmek deyimleri kolayca oluşturmak async ve await anahtar sözcükler.Örneğin, aşağıdaki Windows Forms örnek olay işleyicisini çağırır ve bir zaman uyumsuz yöntem bekler içeren ExampleMethodAsync.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        // ExampleMethodAsync returns a Task.
        await ExampleMethodAsync();
        textBox1.Text += "\r\nControl returned to Click event handler.\r\n";
    }

    async Task ExampleMethodAsync()
    {
        // The following line simulates a task-returning asynchronous process.
        await Task.Delay(1000);
    }
}

Zaman uyumsuz lambda kullanarak aynı olay işleyicisi ekleyebilirsiniz.Bu işleyici eklemek için add bir async lambda parametre listesi, aşağıdaki örnekte gösterildiği gibi önce değiştiricisi.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        button1.Click += async (sender, e) =>
        {
            // ExampleMethodAsync returns a Task.
            await ExampleMethodAsync();
            textBox1.Text += "\r\nControl returned to Click event handler.\r\n";
        };
    }

    async Task ExampleMethodAsync()
    {
        // The following line simulates a task-returning asynchronous process.
        await Task.Delay(1000);
    }
}

Zaman uyumsuz yöntemleri kullanma konusunda daha fazla bilgi için bkz: Zaman uyumsuz zaman uyumsuz programlama ve beklemek (C# ve Visual Basic).

Lambda ile standart sorgu işleçleri

Birçok standart sorgu işleçleri türü olan bir giriş parametresi vardır, Func<T, TResult> genel temsilciler ailesi.Func<T, TResult> Temsilciler tür parametreleri sayısı ve türü giriş parametreleri ve temsilci dönüş türünü tanımlamak için kullanın.FuncTemsilciler çok kaynak veri kümesi içindeki her öğesine uygulanan kullanıcı tanımlı ifadeleri kapsüllenmesinde kullanışlıdır.Örneğin, aşağıdaki temsilci türünü göz önünde bulundurun:

public delegate TResult Func<TArg0, TResult>(TArg0 arg0)

Temsilci olarak oluşturulabilir Func<int,bool> myFunc burada int bir giriş parametresidir ve bool dönüş değeri.Dönüş değeri, her zaman son türü parametresinde belirtilir.**Func<int, string, bool>**bir temsilci ile iki giriş parametreleri tanımlar int ve stringve dönüş türü bool.Aşağıdaki Func , temsilci çağrıldığında, döndürür true veya false giriş parametresi 5'e eşit olup olmadığını belirtmek için:

Func<int, bool> myFunc = x => x == 5;
bool result = myFunc(4); // returns false of course

Bağımsız değişken türü aynı zamanda lambda ifadesi tedarikini sağlayabilecek bir Expression<Func>, örneğin System.Linq.Queryable içinde tanımlanan standart sorgu işleçler de.Belirttiğinizde bir Expression<Func> bağımsız değişkeni, bir ifade ağacı lambda derlenecek.

Standart sorgu işleci, Count yöntemi, burada gösterilen:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);

Derleyicinin türü giriş parametresi çıkarabilir ya da bunu açıkça belirtebilirsiniz.Bu belirli lambda ifadesi bu tamsayılar sayar (n), 1 kalanını iki bölünmüş olur.

Aşağıdaki yöntem, tüm öğeleri içeren bir dizi üretecektir numbers , koşulunu karşılamıyor sıradaki ilk sayı olduğundan, solunda 9 dizisi:

var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);

Bu örnek, parantez içine alarak, birden çok giriş parametrelerini belirtmek nasıl gösterir.Sayı kadar sayıları dizideki tüm öğelerin değerini konumuna küçüktür karşılaşılan yöntem döndürür.Lambda işleci karıştırmayın (=>) ile büyüktür veya eşittir operatörü (>=).

var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);

Tür çıkarımı, lambda

Lambda yazarken, genellikle derleyici lambda gövde, temeldeki temsilci türünü ve C# dil belirtimi içinde açıklandığı gibi diğer etkenler temel tür çıkarımını yaptığı giriş parametreleri için bir tür belirtmek gerekmez.Çoğu standart sorgu işleçler ilk giriş kaynak dizideki öğelerin türüdür.Sorguluyorsanız böyle bir IEnumerable<Customer>, sonra da giriş değişkeni olarak algılanır bir Customer nesnesi yöntemleri ve özellikleri için erişim iznine sahip anlamına gelir:

customers.Where(c => c.City == "London");

Lambda için genel kurallar şunlardır:

  • Lambda temsilci türüyle aynı sayıda parametresi içermelidir.

  • Her giriş parametresi lambda içinde karşılık gelen temsilci parametre örtük olarak dönüştürülebilir olmalıdır.

  • Lambda (varsa) dönüş değeri temsilcinin dönüş türüne örtük olarak dönüştürülebilir olmalıdır.

Not ortak tür sistemi iç "lambda ifadesi" kavramı olduğundan lambda ifadeleri kendi içinde bir tür yok Ancak, bazen "türünü" lambda ifadesinin basit konuşmak uygundur.Bu gibi durumlarda türü temsilci türüne başvurur veya Expression lambda ifadesi dönüştürülmüş yazın.

Lambda ifadeleri değişken kapsamı

Lambda başvuru yapabilir dış değişkenleri kapsayan yöntemi veya lambda tanımlanır türü kapsamında bulunan.Bu şekilde yakalanan değişkenleri değişkenleri kapsam dışı Aksi durumda geçerek bile ve toplanacak çöp lambda ifadesinde kullanım için saklanır.Lambda ifadesinde tüketilebilir önce bir dış değişkeni kesinlikle atanmış olması gerekir.Bu kurallar aşağıdaki örnekte gösterilmiştir:

delegate bool D();
delegate bool D2(int i);

class Test
{
    D del;
    D2 del2;
    public void TestMethod(int input)
    {
        int j = 0;
        // Initialize the delegates with lambda expressions.
        // Note access to 2 outer variables.
        // del will be invoked within this method.
        del = () => { j = 10;  return j > input; };

        // del2 will be invoked after TestMethod goes out of scope.
        del2 = (x) => {return x == j; };
      
        // Demonstrate value of j:
        // Output: j = 0 
        // The delegate has not been invoked yet.
        Console.WriteLine("j = {0}", j);        // Invoke the delegate.
        bool boolResult = del();

        // Output: j = 10 b = True
        Console.WriteLine("j = {0}. b = {1}", j, boolResult);
    }

    static void Main()
    {
        Test test = new Test();
        test.TestMethod(5);

        // Prove that del2 still has a copy of
        // local variable j from TestMethod.
        bool result = test.del2(10);

        // Output: True
        Console.WriteLine(result);
           
        Console.ReadKey();
    }
}

Lambda ifadeleri değişken kapsamı için aşağıdaki kurallar geçerlidir:

  • Yakalanan bir değişken atık başvurduğu temsilci kapsam dışında gider kadar toplanan değil.

  • Lambda ifadesi içinde tanıtılan değişkenleri dış yöntem içinde görünmez.

  • Lambda ifadesi doğrudan yakalayamazsınız bir ref veya out kapsayan bir yöntem parametresi.

  • Lambda ifadesinde bir dönüş ifadesi dönmek kapsayan yöntemi neden olmaz.

  • Lambda ifadesi içeremez bir goto ifadesi, break deyimi, ya da continue hedefi olan gövde dışında veya içerdiği bir anonim işlev gövdesi içinde deyim.

C# dil belirtimi

Daha fazla bilgi için bkz: C# dil belirtiminin. Dil belirtimi, C# sözdizimi ve kullanımı için nihai kaynaktır.

Özel Kitap bölüm

C# 3.0 Cookbook, Third Edition: More than 250 solutions for C# 3.0 programmers içinde Delegates, Events, and Lambda Expressions

Ayrıca bkz.

Başvuru

Adsýz yöntemler (C# Programlama Kılavuzu)

(C# Başvurusu)

Kavramlar

C# Programlama Kılavuzu

İfade ağaçları (C# ve Visual Basic)

Diğer Kaynaklar

LINQ (dil ile bütünleşik sorgu)

Özyinelemeli lambda ifadeleri