簡體   English   中英

泛型和擴展方法-IntelliSense如何推斷類型?

[英]Generics and Extension Methods - how does IntelliSense infer types?

我有一個關於編譯器在使用泛型和擴展方法時如何推斷類型的問題。 問我問題的最簡單方法是先顯示一些代碼...

我有一個看起來像這樣的ViewModelBase類(刪除了所有不相關的內容)。 基本上,每次應用程序進入與其鏈接的View時,我的NavigationService類都會調用NavigatingTo方法。

此類的繼承者可以調用Return委托,以將數據傳遞回調用者。

public abstract class ViewModelBase<TContext, TReturn>
{
    public Action<TReturn> Return { get; set; }

    public abstract void NavigatingTo(TContext context);
}

然后,我有一個繼承ViewModelBase的測試ViewModel:

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方法需要一個帶有TContext和TReturn的ViewModelBase,編譯器應該能夠推斷出實際使用的類型:

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)

解決此問題的方法之一是將TContext和TReturn類型參數傳播到NavigationCommand,因此其聲明如下所示:

public class NavigationCommand<TViewModel, TContext, TReturn> where TViewModel:ViewModelBase<TContext, TReturn>

但這會使命令初始化更加冗長(因為TestViewModel類型實際上已經包含有關TContextTReturn實際類型的信息):

var cmd = new NavigationCommand<TestViewModel, int, bool>(vm);

實際上,您發布的實現已經是類型安全的,並且不允許您傳遞錯誤類型的參數(比如說用string代替int )。 唯一的問題是Intellisense,由於某種原因,它無法正確推斷類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM