Какой странный вызов метода это? - PullRequest
4 голосов
/ 21 октября 2010

Я только что прочитал учебник Microsoft Surface. Существует следующий пример 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 ]

5 голосов
/ 21 октября 2010

Это лямбда-выражения, генерирующие анонимные методы.

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), должен быть задан в качестве параметра,Лямбда-выражение генерирует этот метод на лету.(Это делается компилятором, поэтому не выполняется во время выполнения и полностью проверяется на тип и не приводит к потере производительности).

5 голосов
/ 21 октября 2010

То, что вы видите ниже, является лямбда-выражением C #

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

По сути, это выражение, которое создает делегат.Некоторым людям нравится думать о них как о встроенных функциях.

Вот некоторые ссылки для чтения

2 голосов
/ 21 октября 2010

d => d.GetType() == typeof(ScatterViewItem) называется лямбда-выражением.Он говорит: «Для любого 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 не заботится о том, как происходит операция, он может просто вызвать ее и знать, что получит полезный ответ.

1 голос
/ 21 октября 2010

=> - это новый "лямбда-оператор" для определения функций на лету.

См .: www.switchonthecode.com / tutorials / csharp-tutorial-the-lambda-operator

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...