使用委托c#

本文关键字: | 更新日期: 2023-09-27 18:08:53

我是新手,我想知道第一个代码和第二个代码的区别

我有一个类

public class FindPerson
{
    public int Age;
    public string Name;
    public string Surname;
    public FindPerson(string name, string surname, int age)
    {
        this.Age = age;
        this.Surname = surname;
        this.Name = name;
    }
    public override string ToString()
    {
        return "Name=" + this.Name + " Surname=" + this.Surname + ", Age=" + this.Age.ToString();
    }
}

第一个代码

public void Test2()
{
    List<FindPerson> lst = new List<FindPerson>();
    lst.Add(new FindPerson("Alex","Sweit",31));
    lst.Add(new FindPerson("Alex2", "Sweit", 30));
    lst.Add(new FindPerson("Alex3", "Sweit", 34));
    FindPerson iam = lst.Find(a => a.Name.Equals("Alex"));
}
第二代码:

public void Test2()
{
    List<FindPerson> lst = new List<FindPerson>();
    lst.Add(new FindPerson("Alex","Sweit",31));
    lst.Add(new FindPerson("Alex2", "Sweit", 30));
    lst.Add(new FindPerson("Alex3", "Sweit", 34));
    FindPerson iam2 = lst.Find(new Predicate<FindPerson>(delegate(FindPerson find)
    {
        return find.Name.Equals("Alex");
    }));
}

我正在学习使用委托,但不清楚。

使用委托c#

本质上是一样的

delegate() { }语法在c# 2.0中引入,而lambda语法在c# 3.0中引入。它们的设计目标不同,但目的是一致的。

让我引用Eric Lippert的话(它在他的十大最差c#特性中排名第七):

我想所有相关的人都会同意,对于基本上相同的事情有两种不一致的语法是不幸的。但是c#仍然坚持使用它,因为现有的c# 2.0代码仍然使用旧的语法。

c# 2.0语法的"厚重"在当时被认为是一个好处。当时的想法是,用户可能会对嵌套方法的这个新特性感到困惑,设计团队希望在那里有一个明确的关键字,表明嵌套方法正在被转换为委托。没有人能预见到未来会需要一种更轻量级的语法。

现在你不会看到delegate() { }语法在新代码中使用得太多,因为实际上每个人都更喜欢更轻的lambda =>语法。

new Predicate<FindPerson>只是显式地键入委托,不再需要。它曾经在c# 1 IIRC中是强制性的。在大多数情况下,它可以被推断出来,因此可以省略(在需要时,请参阅此处的示例)。

它的存在是由于lambda是由底层的类实例表示的,在这个特殊的例子中,Predicate<T>就是那个类。"原始"lambda本身是无类型的,但它可以隐式地转换为任何兼容的委托类型。

例如,Predicate<FindPerson>在这个例子中是一个兼容的委托类型,但Func<FindPerson, bool>也是。同样的lambda也可以转换为Expression<Func<FindPerson, bool>>,但这是一个完全不同的问题。这就是为什么你不能在c#中编写var fn = (int x) => x;,如fn的类型不能单独从这个表达式中推断出来。

概括一下,这些都是等价的:

// Compact lambda
lst.Find(a => a.Name.Equals("Alex"))
// Explicitly typed parameter
lst.Find((FindPerson a) => a.Name.Equals("Alex"))
// Explicit delegate type
lst.Find(new Predicate<FindPerson>(a => a.Name.Equals("Alex")))
// Combination of the two above
lst.Find(new Predicate<FindPerson>((FindPerson a) => a.Name.Equals("Alex")))
// Explicit delegate type through casting
lst.Find((Predicate<FindPerson>)(a => a.Name.Equals("Alex")))
// Lambda block
lst.Find(a => { return a.Name.Equals("Alex"); })
// Delegate block
lst.Find((Predicate<FindPerson>)(delegate(FindPerson a) { return a.Name.Equals("Alex"); }))
// ... etc

第一个例子使用了所谓的"lambda"表达式(在。net 3.5中引入),这是一种更简单、更简洁(而且我认为)更优雅的方式来表达匿名委托。第二段代码是做同样事情的更老、更冗长的方式。

它们在生成的IL代码方面是相同的。不过,第一种格式读起来和写起来要好得多,而且通常更常见。委托现在已经很少使用了。

除了语法之外没有区别。

Find方法期望Predicate<T>作为参数,由您决定是否使用new关键字自己创建它,或者传递lambda表达式并让编译器为您完成。
相关文章:
  • 没有找到相关文章