2011-08-22 27 views
1

我最近和vb.net一起工作並且遇到了一個帶有泛型的工廠模式問題。儘管我已經解決了它,但我不知道它爲什麼在vb.net中不起作用。我有幾年的C#經驗,我有時會在c#中編寫如下代碼,並且沒有任何問題。在c#中使用泛型的工廠模式工作,但在vb.net中不起作用,爲什麼?

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的限制嗎?

回答

4

主要原因是VB中的DirectCast更像是C#(cast)運算符而不是as運算符。 C#代碼工作,因爲as只返回nullTestDerived不是TestBase<T>(這是任何時候TTestItem)。 DirectCast居然會失敗,如果TestDerived不是TestBase(Of T),所以你看到的錯誤。

您可以通過使用Typeof Is construct,或使用TryCast()獲得VB類似的功能。

另外,你可以讓TestDerived實際上繼承TestBase<T>,(因此使得TestDerived<T>),這將使一切工作,而不用兩種語言鑄造。

用C
+0

好吧,我知道了。爲什麼TestDerived需要從TestBase 繼承的主要原因是在實際的代碼每個派生類希望把重點放在了每個具體類做一些獨特的作品,所以我花了一段日子要怎麼解決。無論如何,你幫助我瞭解發生了什麼。謝謝dlev​​。 –

2

a as T#對應於TryCast(a, T)[MSDN]在VB(未DirectCast)。

+0

是的,我現在明白了。但是,即使我改變DirectCast到TryCast上述代碼'TryCast(新TestDerived(),TestBase(中T))',它仍然給了我一個編譯錯誤:( –

相關問題