2013-12-13 6 views
0

Это прекрасно работает:Почему аргумент «Делегат» принимает только делегат RoutedEventHandler?

EventManager.RegisterClassHandler(typeof(DataGrid),  
     DataGrid.SelectionChangedEvent,  
     new RoutedEventHandler(ScrollToSelectedItem)); 

void ScrollToSelectedItem(object sender, RoutedEventArgs e) 

компилируется, но дает во время выполнения исключение: типа Handler является несовпадающими:

EventManager.RegisterClassHandler(typeof(DataGrid),  
     DataGrid.SelectionChangedEvent,  
     new Action<object, RoutedEventArgs>( 
     (object sender, RoutedEventArgs e1) =>  
     ScrollToSelectedItem(sender, e1, false))); 

    void ScrollToSelectedItem(object sender, RoutedEventArgs e, bool jump) 

Третий параметр RegisterClassHandler объявлен Delegate handler.

Неявно предполагается, что обработчик является не только делегатом, но и делегатом RoutedEventHandler?
Тогда почему у RegisterClassHandler не более точная подпись?

EDIT только что обнаружил, что я могу решить эту проблему с помощью:

RoutedEventHandler htrue = (o, ea) => ScrollToSelectedItem(o, ea, true); 
RoutedEventHandler hfalse = (o, ea) => ScrollToSelectedItem(o, ea, false); 
void ScrollToSelectedItem(object sender, RoutedEventArgs e, bool jump) 
EventManager.RegisterClassHandler(typeof(DataGrid),  
     DataGrid.SelectionChangedEvent, hfalse); 

ответ

2

Просто потому, что две разные делегаты имеют одинаковую сигнатуру, не делает их такими же, по той же причине, что следующие два типа не то же самое:

public class Foo { public int n; } 
public class Bar { public int n; } 

Вы не можете назначить Foo до Bar только потому, что у них одинаковые поля экземпляра.

Action - это тип, как и RoutedEventHandler, и между ними нет неявного преобразования.

Тогда почему у RegisterClassHandler нет более точной подписи?

Что касается того, почему у него нет более определенной подписи, я не мог сказать, что я не проектировал класс. Похоже, что это не очень хорошо спроектировано, хотя, учитывая ваше замешательство. Вероятно, должен иметь определенный делегат как необходимый параметр.

+0

Можно ли (неявно) преобразовать 'Action ' в 'RoutedEventHandler'? – Gerard

+0

@Gerard Нет, это не так. – Servy

+0

@Servy, 'public static implicit operator RoutedEventHandler (Action act)' - не то, что это обязательно отличная идея, но эй ... –

0

Делегат (в верхнем регистре) является классом. делегат (строчный регистр) - это тип.

Действие <> возвращает делегат (нижний регистр), который не передается делегату (в верхнем регистре), насколько я могу судить.

+0

RoutedEventHandler - это lc-делегат и отлично работает при передаче параметра uc-Delegate. 'Action ' также является lc-делегатом, с первого взгляда того же типа, что и RoutedEventHandler (но не в соответствии с ответом Servy). – Gerard

+2

@Gerard Нет, это не тот же тип. Это совсем другой тип. У него просто такая же подпись; это совсем другое. – Servy

Смежные вопросы