在下面的代码中,我调用扩展方法[平均] 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;
}
}
解决方法:
您无法在C#中从一种类型的委托转换为另一种委托.由于IEnumerable<T>.Average
需要一个Func< T,int>,这是您需要提供的委托,而不管与myDelegate具有相同签名的事实.
你可以改变这个:
myDelegate myDel = new myDelegate(myPerson.GetAge);
成:
Func<Person, int> myDel = new Func<Person, int>(myPerson.GetAge);
或者只是将方法作为参数传递,这将为您创建适当的委托:
double averageAge3 = people.Average(myPerson.GetAge); // this will work
请注意,使GetAge成为实例方法(与静态方法相比)没有意义,因为它返回作为参数传递的对象的年龄,而不是父(此)对象.
当您查看myPerson对象时,这会变得很明显,该对象使用“虚拟”值进行实例化,只是为了访问其GetAge方法,该方法不使用任何属性(您可以简单地编写double averageAge3 = people.Average (new Person().GetAge);什么都不会改变).
我建议使用匿名方法(首选),或使GetAge方法保持静态.