【问题标题】:How can I make this generic我怎样才能使这个通用
【发布时间】:2011-09-22 08:13:28
【问题描述】:

我有一堆 ViewModel 类,Q001ViewModel、Q002ViewModel、...、QnnnViewModel。这些都继承自 VMBase。

我还有一组 Subs ShowQnnn, ShowQnnn, ..., ShowQnnn。一个例子是:

    Private Sub ShowQ001()
        Dim workspace As Q001ViewModel = _
            CType(Me.Workspaces.FirstOrDefault(Function(vm) vm.GetType() Is GetType(Q001ViewModel)), Q001ViewModel)

        If workspace Is Nothing Then
            workspace = New Q001ViewModel(_dbc)
            Me.Workspaces.Add(workspace)
        End If

        Me.SetActiveWorkspace(workspace)
    End Sub

Workspaces 是 VMBase 的 ObservableCollection。

ShowQnnn 过程用于显示 ViewModel。关键是,只有当其中一个类型不存在时,才会将新的 QnnnViewModel 添加到工作区集合中。

有没有办法将 ShowQnnn 程序变成一个通用版本?

【问题讨论】:

    标签: .net vb.net generics mvvm


    【解决方案1】:

    抱歉,我对泛型的 VB.Net 语法不够了解(请随时使用 VB.Net 版本编辑我的答案),所以我会用 C# 回答。

    如果构造函数采用不同的参数,解决方案将如下所示:

    void ShowQxxx<T>(Func<T> constructor)
        where T : VMBase
    {
        var workspace = (T)(Workspaces.FirstOrDefault(vm => vm is T);
    
        if (workspace == null)
        {
            workspace = constructor();
            Workspaces.Add(workspace)
        }
    
        SetActiveWorkspace(workspace)
    }
    
    ...
    
    ShowQxxx(() => new Q001ViewModel(_dbc));
    

    否则你可以使用反射来简化更多:

    void ShowQxxx<T>()
        where T : VMBase
    {
        var workspace = (T)(Workspaces.FirstOrDefault(vm => vm is T);
    
        if (workspace == null)
        {
            var ctor = typeof(T).GetConstructor(new [] { typeof(MyDataBaseType) });
            workspace = (T)(ctor.Invoke(_dbc));
            Workspaces.Add(workspace)
        }
    
        SetActiveWorkspace(workspace)
    }
    
    ...
    
    ShowQxxx<Q001ViewModel>();
    

    【讨论】:

    • 看起来很棒。将使用 VB.Net 版本进行测试并返回报告
    • 第一个选项中的类型不是省略了吗,所以应该是 ShowQxxx(() => new Q001ViewModel(_dbc)); ?
    • 我在调用中省略了类型,因为最近版本的 C# 编译器能够从 lambda 的结果类型推断它
    • 好的,这也适用于 VB.Net - 所以我更新了下面的 VB 版本。再次感谢!
    【解决方案2】:

    这是VB版

        Private Sub ShowQxxx(Of T As VMBase)(constructor As Func(Of T))
            Dim workspace As T = _
                CType(Me.Workspaces.FirstOrDefault(Function(vm) vm.GetType() Is GetType(T)), T)
    
            If workspace Is Nothing Then
                workspace = constructor()
                Me.Workspaces.Add(workspace)
            End If
    
            Me.SetActiveWorkspace(workspace)
        End Sub
    ....
    
        ShowQxxx(Function() New Q001ViewModel(_dbc))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      • 2014-01-05
      相关资源
      最近更新 更多