Derlendiğinde, arasında bir fark var mı:
delegate { x = 0; }
ve
() => { x = 0 }
?
Derlendiğinde, arasında bir fark var mı:
delegate { x = 0; }
ve
() => { x = 0 }
?
Yanıtlar:
Kısa cevap: hayır.
Alakalı olmayan daha uzun cevap:
Func
veya gibi Action
) atarsanız, anonim bir temsilci alırsınız.Düzenleme: İşte İfadeler için bazı bağlantılar.
Amy'nin cevabını seviyorum ama bilgiçlik yapacağımı düşündüm. Soru, "Bir kez derlendi" der - bu da her iki ifadenin de derlendiğini gösterir. Her ikisi de nasıl derlenebilir, ancak biri delege, diğeri de ifade ağacına dönüştürülürse? Bu zor bir şey - anonim yöntemlerin başka bir özelliğini kullanmanız gerekir; lambda ifadeleri tarafından paylaşılmayan tek kişi. Eğer parametre listesine belirtmeden anonim yöntemi belirtirseniz hiç herhangi temsilci türü boş dönen ve herhangi olmadan uyumludur out
parametreler. Bu bilgiyle donanmış olarak, ifadeleri tamamen açık ama çok farklı hale getirmek için iki aşırı yük inşa edebilmeliyiz.
Ama felaketler! En azından C # 3.0 ile, blok gövdeli bir lambda ifadesini bir ifadeye dönüştüremezsiniz - veya bir lambda ifadesini gövdede bir atamayla (dönüş değeri olarak kullanılsa bile) dönüştüremezsiniz. Bu, bir ifade ağacında daha fazlasının ifade edilmesine izin veren C # 4.0 ve .NET 4.0 ile değişebilir. Başka bir deyişle, MojoFilter'in verdiği örneklerle, ikisi neredeyse her zaman aynı şeye dönüştürülecek. (Bir dakika içinde daha fazla ayrıntı.)
Cesetleri biraz değiştirirsek delege parametrelerini kullanabiliriz:
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...");
}
}
Fakat bekle! Eğer yeterince kurnazsak, ifade ağaçları kullanmadan bile bu ikisi arasında ayrım yapabiliriz. Aşağıdaki örnekte aşırı yük çözünürlüğü kuralları (ve anonim delege eşleştirme hilesi) kullanılmıştır ...
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; } );
}
}
Ahh. Çocukları hatırlayın, bir temel sınıftan miras alınan bir yöntemi her aşırı yüklediğinizde, küçük bir yavru kedi ağlamaya başlar.
delegate { ... }
olduğu değil aynı delegate() { ... }
ikincisi parametresiz temsilci türü ile uyumludur -.
Yukarıdaki iki örnekte hiçbir fark yoktur, sıfır.
İfade:
() => { x = 0 }
ifade gövdesine sahip bir Lambda ifadesidir, bu nedenle bir ifade ağacı olarak derlenemez. Aslında derlenmez, çünkü 0'dan sonra noktalı virgül gerekir:
() => { x = 0; } // Lambda statement body
() => x = 0 // Lambda expression body, could be an expression tree.
Amy B doğru. İfade ağaçlarını kullanmanın avantajları olabileceğini unutmayın. LINQ to SQL, ifade ağacını inceler ve SQL'e dönüştürür.
Ayrıca sınıf üyelerinin adlarını yeniden düzenleme-güvenli bir şekilde bir çerçeveye etkili bir şekilde aktarmak için lamdalar ve ifade ağaçları ile hileler oynayabilirsiniz. Adedi bunun bir örneğidir.
Bir fark var
Misal:
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(delegate
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
Ve lambda ile değiştiriyorum: (hata)
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(()=>
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
Burada bazı temel bilgiler.
Bu anonim bir yöntemdir
(string testString) => { Console.WriteLine(testString); };
Anonim yöntemlerin isimleri olmadığından, bu yöntemlerin veya ifadelerin her ikisini de atayabileceğimiz bir temsilciye ihtiyacımız var. Örneğin
delegate void PrintTestString(string testString); // declare a delegate
PrintTestString print = (string testString) => { Console.WriteLine(testString); };
print();
Lambda ifadesi ile aynı. Genellikle onları kullanmak için bir temsilciye ihtiyacımız var
s => s.Age > someValue && s.Age < someValue // will return true/false
Bu ifadeyi kullanmak için bir işlev temsilcisi kullanabiliriz.
Func< Student,bool> checkStudentAge = s => s.Age > someValue && s.Age < someValue ;
bool result = checkStudentAge ( Student Object);