[英]C# question about a delegate
在下面的代码中,我调用了扩展方法 [平均] 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
成为实例方法(与 static 方法相比)没有意义,因为它返回作为参数传递的 object 的年龄,而不是父级( this
) ZA8CFDE6331BD59EB6666F891ZB41。
当您查看myPerson
object 时,这一点变得很明显,它使用“虚拟”值进行实例化,只是为了访问其GetAge
方法,该方法不使用其任何属性(您可以简单地编写double averageAge3 = people.Average(new Person().GetAge);
什么都不会改变)。
我建议要么使用匿名方法(首选),要么使用GetAge
方法static
。
没有定义扩展方法Average()的重载,它采用myDelegate
类型的参数。
与您的情况相匹配的情况如下:
public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector);
您必须使用Func<T,TReturn>
而不是myDelegate
使其工作。
Person myPerson = new Person { FirstName = "Hanne", LastName = "Schokkele", Age = 7 };
Func<Person, Int32> myDel = myPerson.GetAge;
double averageAge = people.Average(p => p.Age);
double averageAge2 = people.Average(delegate(Person p) { return p.Age; });
double averageAge3 = people.Average(myDel);
你可以做double averageAge3 = myDel.Invoke(myPerson);
或者您希望它看起来如何?
你应该标记你的代表 static (它没有实例上下文)
public static int GetAge(Person p)
然后定义
myDelegate myDel = Person.GetAge;
或直接致电
double averageAge3 = Person.Average(myPerson.GetAge);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.