关于代表的C#问题

Her*_*art 3 c# delegates average

在下面的代码中,我调用扩展方法[平均] 3次.首先是lambda,然后是匿名方法,第三个是委托.

委托的方式不起作用.有人可以解释一下为什么吗?

很多人提前!

- - - - - -码 - - - - - - -

using System.Linq;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        List<Person> people = new List<Person> {
            new Person { FirstName = "William", LastName = "Schokkele", Age = 35 },
            new Person { FirstName = "Bill",    LastName = "Gates", Age = 50 },
            new Person { FirstName = "Hanne",   LastName = "Schokkele", Age = 7 }
        };

        Person myPerson = new Person { FirstName = "Hanne", LastName = "Schokkele", Age = 7 };
        myDelegate myDel = new myDelegate(myPerson.GetAge);

        double averageAge= people.Average(p => p.Age);
        double averageAge2 = people.Average(delegate(Person p) { return p.Age; });
        double averageAge3 = people.Average(myDel); //THIS LINE DOESNT WORK. ERROR MESSAGE LIST<Person> does not contains a definition for 'average'
    }
}

public delegate int myDelegate(Person p);

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    public int GetAge(Person p)
    {
        return p.Age;
    }
}
Run Code Online (Sandbox Code Playgroud)

Gro*_*roo 9

您无法在C#中从一种类型的委托转换为另一种委托.由于IEnumerable<T>.Average需要一个Func<T, int>,那就是你需要提供的委托,不管事实是有相同的签名myDelegate.

你可以改变这个:

myDelegate myDel = new myDelegate(myPerson.GetAge);
Run Code Online (Sandbox Code Playgroud)

成:

Func<Person, int> myDel = new Func<Person, int>(myPerson.GetAge);
Run Code Online (Sandbox Code Playgroud)

或者只是将方法作为参数传递,这将为您创建适当的委托:

double averageAge3 = people.Average(myPerson.GetAge);  // this will work
Run Code Online (Sandbox Code Playgroud)

请注意,创建GetAge实例方法(与静态方法相比)没有意义,因为它返回作为参数传递的对象的年龄,而不是parent(this)对象.

当您查看myPerson使用"虚拟"值实例化的对象时,这变得很明显,只是为了访问其GetAge方法,该方法不使用任何属性(您可以简单地编写double averageAge3 = people.Average(new Person().GetAge);并且不会改变任何内容).

我建议使用匿名方法(首选),或制作您的GetAge方法static.