У меня есть вопрос о том, как компилятор выводит типы при использовании обобщенных методов и методов расширения. Самый простой способ задать мой вопрос - сначала показать код ...
У меня есть класс ViewModelBase, который выглядит примерно так (с удалением всего, что не имеет значения). По сути, мой класс NavigationService вызывает метод NavigatingTo каждый раз, когда приложение переходит в представление, с которым оно связано.
Наследники этого класса могут вызывать делегат Return для передачи данных вызывающей стороне.
public abstract class ViewModelBase<TContext, TReturn>
{
public Action<TReturn> Return { get; set; }
public abstract void NavigatingTo(TContext context);
}
Тогда у меня есть тестовая модель ViewModel, которая наследует ViewModelBase:
public class TestViewModel : ViewModelBase<int, bool>
{
public override void NavigatingTo(int context)
{
// do stuff here
}
}
Далее у меня есть универсальный класс NavigationCommand, который принимает ViewModelBase, например:
public class NavigationCommand<TViewModel>
{
public TViewModel ViewModel { get; set; }
public NavigationCommand(TViewModel viewModel)
{
this.ViewModel = viewModel;
}
}
И, наконец, у меня есть метод расширения для класса NavigationCommand, чтобы добавить к нему метод Navigate. Моя цель заключается в том, чтобы, заявив, что моему методу Navigate требуется ViewModelBase с TContext и TReturn, компилятор должен иметь возможность определить, какие типы фактически должны использоваться:
public static class NavigationExtensions
{
// I actually pass in a INavigationService here too, but I have left that out to
// make it easier to read...
public static void Navigate<TViewModel, TContext, TReturn>(
this NavigationCommand2<TViewModel> viewModel,
TContext context,
Action<TReturn> returnAction)
where TViewModel : ViewModelBase<TContext, TReturn>
{
// actual implementation omitted
}
}
Хорошо, теперь в моем классе ApplicationController я делаю следующее:
var vm = new TestViewModel();
var cmd = new NavigationCommand2<TestViewModel>(vm);
int clientID = 1;
Action<bool> returnAction = success =>
{
Console.WriteLine(success.ToString());
};
cmd.Navigate(clientID, returnAction);
Это работает, и если вы попытаетесь передать неправильный тип, вы получите ошибку компилятора при сборке. Однако Intellisense не запрашивает правильные типы.
Итак, мой вопрос: есть ли способ переписать метод расширения или мой класс NavigationCommand или ViewModel и т. Д., Чтобы Intellisense фактически подсказывал мне использовать правильный тип?
В настоящее время все, что Intellisense дает мне, это:
(extension void) NavigateCommand<TestViewModel>.Navigate(TContext context, Action<TReturn> returnAction)
Когда то, что я хочу, это:
(extension void) NavigateCommand<TestViewModel>.Navigate(int context, Action<bool> returnAction)