工厂模式与通用在c#工作,但在vb.net,不起作用,为什么?

时间:2011-08-22 05:58:48

标签: 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的限制吗?

2 个答案:

答案 0 :(得分:4)

主要原因是VB中的DirectCast更像是C#(cast)运算符而不是as运算符。 C#代码有效,因为当as不是null时,TestDerived只会返回TestBase<T>T不是TestItem DirectCast })。如果TestDerived不是TestBase(Of T),则TestDerived实际上会失败,因此您会看到错误。

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

或者,您可以让TestBase<T>实际上继承自TestDerived<T>,从而制作{{1}}),这样可以在不使用两种语言进行投射的情况下完成所有工作。

答案 1 :(得分:2)

C#中的

a as T对应于VB中的TryCast(a, T) [MSDN] (不是DirectCast)。