c# - 带有泛型的工厂模式在 C# 中有效,但在 vb.net 中不起作用,为什么?

标签 c# vb.net

我最近在使用 vb.net 时遇到了泛型工厂模式的问题。虽然我已经解决了,但我不知道为什么它在 vb.net 中不起作用。我有几年的 c# 经验,有时我会在 c# 中编写如下代码,并且它可以正常运行。

public class GenericTest
{
    public static void Test()
    {
        var test = Factory<TestItem>.GetTest(ProcessType.Derived);
        test.Do();
    }
}

public class TestItem
{
    public int Property1 { get; set; }
}

public class TestBase<T> where T: class
{
    public virtual void Do()
    {
        Console.WriteLine(typeof(T).ToString());
    }
}

public class TestDerived : TestBase<TestItem>
{
    public override void Do()
    {
        Console.WriteLine(typeof(TestItem).ToString());
    }
}

public class Factory<T> where T:class
{
    public static TestBase<T> GetTest(ProcessType processType)
    {
        switch (processType)
        {
            case ProcessType.Derived :
                return new TestDerived() as TestBase<T>;
            default:
                return new TestBase<T>();
        }
    }
}

public enum ProcessType
{
    Base,
    Derived
}

但是当我把上面的代码移植到vb.net时,编译器报错了。

Public Class GenericTest
    Public Shared Sub Test()
        Dim test = Factory(Of TestItem).GetTest(ProcessType.Derived)
        test.DoIt()
    End Sub
End Class    

Public Class TestItem
    Public Property Property1 As Integer
End Class

Public Class TestBase(Of T As Class)
    Public Overridable Sub DoIt()
        Console.WriteLine(GetType(T).ToString())
    End Sub
End Class

Public Class TestDerived
    Inherits TestBase(Of TestItem)

    Public Overloads Sub DoIt()
        Console.WriteLine(GetType(TestItem).ToString())
    End Sub
End Class

Public Class Factory(Of T As Class)
    Public Shared Function GetTest(processType As ProcessType) As TestBase(Of T)
        Select Case processType
            Case VB_Sandbox.ProcessType.Derived
                ' This line gives me a compile error saying 'cannot convert TestDerived to TestBase(Of T)'
                Return DirectCast(New TestDerived(), TestBase(Of T))
            Case Else
                Return New TestBase(Of T)
        End Select
    End Function
End Class

Public Enum ProcessType
    Base
    Derived
End Enum

所以,我引入了一个如下界面来让一切正常,这实际上解决了我的问题。

Public Class TestBase(Of T As Class)
    Implements ITest
    Public Overridable Sub DoIt() Implements ITest.DoIt
        Console.WriteLine(GetType(T).ToString())
    End Sub
End Class

Public Class TestDerived
    Inherits TestBase(Of TestItem)

    Public Overloads Sub DoIt()
        Console.WriteLine(GetType(TestItem).ToString())
    End Sub
End Class

Public Class Factory(Of T As Class)
    Public Shared Function GetTest(processType As ProcessType) As ITest
        Select Case processType
            Case VB_Sandbox.ProcessType.Derived
                Return DirectCast(New TestDerived(), ITest)
            Case Else
                Return New TestBase(Of T)
        End Select
    End Function
End Class

Public Interface ITest
    Sub DoIt()
End Interface

这只是 vb.net 的限制吗?

最佳答案

主要原因是DirectCast在 VB 中更像是 C# (cast)运算符比 as运算符(operator)。 C# 代码有效是因为 as只会返回 null什么时候TestDerived不是 TestBase<T> (任何时候 T 都不是 TestItem )。 DirectCast如果 TestDerived 实际上会失败不是 TestBase(Of T) ,所以您会看到错误。

您可以使用 Typeof Is construct 在 VB 中获得类似的功能,或使用 TryCast() .

或者,您可以使用 TestDerived实际上继承自TestBase<T> , (因此生成 TestDerived<T> )这将使一切正常而无需使用两种语言进行转换。

关于c# - 带有泛型的工厂模式在 C# 中有效,但在 vb.net 中不起作用,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7143664/

相关文章:

c# - 绘制低不透明度的填充矩形

c# - 如何在 asp :gridview 中动态创建列

c# - 为什么在 "Windows Class Library"项目中创建时未发现 wcf 服务?

vb.net - 是否有必要在我的响应 header 中设置内容长度?

vb.net - 使用 linq 而不是 foreach 更新列表

vb.net - 在 VB 中获取 CPU 名称、架构和时钟速度

asp.net - 添加数据表和包含数据表的 session

c# - 插件在 Win 7 上的应用刷新页面时崩溃

c# - 将 C++ 字符串传递给 C# 函数

c# - 创建一个 WPF 触摸屏键盘应用程序,将按键发送到另一个窗口