这个奇怪的方法是什么?

时间:2010-10-20 22:57:49

标签: c# lambda

我刚刚阅读了Microsoft Surface Tutorial。有以下C#示例:

private void OnCenterItems(object sender, RoutedEventArgs e)
{
    var x = this.Photos.ActualWidth / 2;
    var y = this.Photos.ActualHeight / 2;
    FindChildren(this.Photos, d => d.GetType() == typeof(ScatterViewItem), 
                          d => ((ScatterViewItem)d).Center = new Point(x,y));
}

private void FindChildren(DependencyObject source, 
                          Predicate<DependencyObject> predicate, 
                          Action<DependencyObject> itemFoundCallback)
{
    int childCount = VisualTreeHelper.GetChildrenCount(source);
    for (int i = 0; i < childCount; i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(source, i);
        if (predicate(child))
        {
            itemFoundCallback(child);
        }
        FindChildren(child, predicate, itemFoundCallback);
    }
}

我想我或多或少地了解这两种方法正在做什么,但我从未见过像这样的方法调用:

 FindChildren(this.Photos, d => d.GetType() == typeof(ScatterViewItem), 
                           d => ((ScatterViewItem)d).Center = new Point(x,y));

这可能是因为我是一名Java程序员。那么任何人都可以解释这种语法在做什么吗?

4 个答案:

答案 0 :(得分:5)

您对以下内容的看法是C#lambda表达式

d => d.GetType() == typeof(ScatterViewItem)

它本质上是一个产生委托的表达式。有些人喜欢将它们视为内联函数。

以下是阅读的一些参考资料

答案 1 :(得分:5)

这些是lambda表达式,生成匿名方法。

d => d.GetType() == typeof(ScatterViewItem)

这可以写成

(object d) => { return (d.GetType() == typeof(ScatterViewItem)); }

这个调用代表了这个方法,如果写出来的话:

public bool CheckObjecteEqualsScatterViewItemType (object d)
{
  return d.GetType() == typeof(ScatterViewItem);
}

方法FindChildren需要一个泛型委托(比较C中的函数指针,但强类型)Func<object, bool>(即任何获取对象并返回bool的方法)作为参数给出,lambda表达式动态生成此方法。 (这是由编译器完成的,所以这是在运行时完成并且是完全类型检查的,并且不会损失性能)。

答案 2 :(得分:2)

d => d.GetType() == typeof(ScatterViewItem)称为Lambda Expression。它说“对于任何DependencyObject,d,return(d.GetType()== typeof(ScatterViewItem))”。这是一种没有名字的方法,一种匿名方法。

长手将是:

static bool myPredicate(DependencyObject d)
{
  return d.GetType() == typeof(ScatterViewItem);
}

呼叫:

FindChildren(this.Photos, myPredicate, [...] )

Predicate<DependencyObject>是委托类型或“签名形状”。它可以保存对任何采用DependencyObject并返回bool的方法的引用。

FindChildren知道使用提供的谓词来评估它应该做的事情。因为它需要某些类型的数据并返回某些类型的数据,所以FindChildren并不关心操作是如何发生的,它可以调用它并知道它会得到一个有用的答案。

答案 3 :(得分:1)

=>是新的“lambda”运算符,用于动态定义函数。

请参阅:www.switchonthecode.com/tutorials/csharp-tutorial-the-lambda-operator