Setelah dikompilasi, apakah ada perbedaan antara:
delegate { x = 0; }
dan
() => { x = 0 }
?
Setelah dikompilasi, apakah ada perbedaan antara:
delegate { x = 0; }
dan
() => { x = 0 }
?
Jawaban:
Jawaban singkat: tidak.
Jawaban yang lebih panjang yang mungkin tidak relevan:
Func
atau Action
) Anda akan mendapatkan delegasi anonim.Sunting: Berikut ini beberapa tautan untuk Ekspresi.
Saya suka jawaban Amy, tetapi saya pikir saya akan menjadi sangat baik. Pertanyaannya mengatakan, "Setelah dikompilasi" - yang menunjukkan bahwa kedua ekspresi telah dikompilasi. Bagaimana mereka bisa mengkompilasi, tetapi dengan satu dikonversi menjadi delegasi dan satu ke pohon ekspresi? Itu rumit - Anda harus menggunakan fitur lain dari metode anonim; satu-satunya yang tidak dibagikan oleh ekspresi lambda. Jika Anda menentukan metode anonim tanpa menentukan daftar parameter sama sekali, itu kompatibel dengan semua jenis delegasi yang kembali batal dan tanpa out
parameter apa pun . Berbekal pengetahuan ini, kita harus dapat membangun dua kelebihan untuk membuat ekspresi yang sama sekali tidak ambigu tetapi sangat berbeda.
Tapi bencana melanda! Paling tidak dengan C # 3.0, Anda tidak bisa mengonversi ekspresi lambda dengan badan blok menjadi ekspresi - juga tidak bisa mengonversi ekspresi lambda dengan tugas di tubuh (bahkan jika itu digunakan sebagai nilai balik). Ini dapat berubah dengan C # 4.0 dan .NET 4.0, yang memungkinkan lebih banyak diekspresikan dalam pohon ekspresi. Jadi dengan kata lain, dengan contoh yang diberikan MojoFilter, keduanya hampir selalu akan dikonversi ke hal yang sama. (Lebih detail dalam satu menit.)
Kita dapat menggunakan trik parameter delegasi jika kita mengubah sedikit tubuh:
using System;
using System.Linq.Expressions;
public class Test
{
static void Main()
{
int x = 0;
Foo( () => x );
Foo( delegate { return x; } );
}
static void Foo(Func<int, int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
static void Foo(Expression<Func<int>> func)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
Tapi tunggu! Kita dapat membedakan antara keduanya bahkan tanpa menggunakan pohon ekspresi, jika kita cukup cerdik. Contoh di bawah ini menggunakan aturan resolusi kelebihan beban (dan trik pencocokan delegasi anonim) ...
using System;
using System.Linq.Expressions;
public class Base
{
public void Foo(Action action)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
public class Derived : Base
{
public void Foo(Action<int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int x = 0;
d.Foo( () => { x = 0; } );
d.Foo( delegate { x = 0; } );
}
}
Aduh. Ingat anak-anak, setiap kali Anda membebani metode yang diwarisi dari kelas dasar, anak kucing kecil mulai menangis.
delegate { ... }
adalah tidak sama dengan delegate() { ... }
- yang terakhir ini hanya kompatibel dengan jenis parameterless delegasi.
Dalam dua contoh di atas tidak ada perbedaan, nol.
Ekspresi:
() => { x = 0 }
adalah ekspresi Lambda dengan tubuh pernyataan, sehingga tidak dapat dikompilasi sebagai pohon ekspresi. Bahkan ia tidak dapat dikompilasi karena memerlukan titik koma setelah 0:
() => { x = 0; } // Lambda statement body
() => x = 0 // Lambda expression body, could be an expression tree.
Amy B benar. Perhatikan bahwa mungkin ada keuntungan menggunakan pohon ekspresi. LINQ ke SQL akan memeriksa pohon ekspresi dan mengubahnya menjadi SQL.
Anda juga dapat bermain trik dengan lamdas dan pohon ekspresi untuk secara efektif menyampaikan nama anggota kelas ke kerangka kerja dengan cara yang aman untuk refactoring. Moq adalah contoh dari ini.
Ada perbedaan
Contoh:
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(delegate
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
Dan saya ganti dengan lambda: (kesalahan)
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(()=>
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
Beberapa dasar di sini.
Ini adalah metode anonim
(string testString) => { Console.WriteLine(testString); };
Karena metode anonim tidak memiliki nama, kami memerlukan delegasi tempat kami dapat menetapkan kedua metode atau ekspresi ini. misalnya
delegate void PrintTestString(string testString); // declare a delegate
PrintTestString print = (string testString) => { Console.WriteLine(testString); };
print();
Sama dengan ekspresi lambda. Biasanya kita membutuhkan delegasi untuk menggunakannya
s => s.Age > someValue && s.Age < someValue // will return true/false
Kita dapat menggunakan delegate func untuk menggunakan ungkapan ini.
Func< Student,bool> checkStudentAge = s => s.Age > someValue && s.Age < someValue ;
bool result = checkStudentAge ( Student Object);