2010-09-17 28 views
0

考慮以下擴展方法:VB.NET通用約束和亞類

<Extension()> _ 
    Public Function Satisfies(Of T)(ByVal subject As T, ByVal specification As ISpecification(Of T)) As Boolean 
     Return specification.IsSatisfiedBy(subject) 
    End Function 

此工作,如果對象是由本說明書在其上操作的確切類如預期。但是,如果規範正在檢查T的超類,那麼除非將主題明確地轉換爲超類,否則此擴展將不起作用。有沒有辦法可以避免這種情況?到目前爲止,我已經能夠拿出最好的是:

<Extension()> _ 
    Public Function Satisfies(Of T As Class, K As Class)(ByVal subject As T, ByVal specification As ISpecification(Of K)) As Boolean 
     Return specification.IsSatisfiedBy(TryCast(subject, K)) 
    End Function 

但我不能不認爲有更好的辦法....

更新:

由於我(顯然)由於語言本身的限制無法完全按照我在VB.NET中的工作方式工作,我的第二次嘗試是以最安全/最有效的方式來執行此操作嗎?

回答

4

這是通過在VB中應用擴展方法的設計。我不知道他們爲什麼爲VB創建不同的擴展,但是對於VB來說,TDerived的限制是:TBase不能存在。不幸的是,沒有它,你不能將TDerived投入到TBase中,因此IsSatisfiedBy函數失敗。供參考:

Extension method '<methodname>' has type constraints that can never be satisfied

你的第一個實施似乎是唯一的一個,將工作,這是的擴展方法是如何設計的VB框架的限制。

+0

感謝您的確認,已更新我的問題,試圖爲此限制獲得合理的解決方法。 – DanP 2010-09-17 19:29:34

1

我在想這樣的事情應該工作,但它並不:

<Extension()> 
Public Function Satisfies(Of TBase, TDerived As TBase)(
      ByVal subject As TDerived, 
      ByVal specification As ISpecification(Of TBase)) As Boolean 
    Return specification.IsSatisfiedBy(subject) 
End Function 

VB編譯器說:「擴展方法‘:滿足’有鍵入就絕不會滿足約束條件」,這是相當奇怪,因爲在C#中,它的工作:

public static class Extensions 
{ 
    public static bool Satisfies<TDerived, TBase>(
       this TDerived subject, 
       ISpecification<TBase> spec) where TDerived:TBase 
    { 
     return spec.IsSatisfiedBy(subject); 
    } 
} 

public interface ISpecification<T> 
{ 
    bool IsSatisfiedBy(T subject); 
} 

因此,答案似乎是:使用C#這個結構,或者像@Dario指出,貫徹落實:滿足法作爲常規組件的方法,而不是一個擴展方法。

+1

這真的很奇怪,是的。最重要的是因爲沒有'',它就可以工作。 – Dario 2010-09-17 19:12:15

+0

我試過這個完全相同的東西..不幸的是,切換到C#不是真的一個選項..我不相信有沒有辦法在VB.NET中做到這一點.... – DanP 2010-09-17 19:17:24

+0

@DanP我會只需將ISpecification接口和擴展方法放在一個單獨的(C#)項目中即可。你不必切換你的整個項目,但至少這種情況會起作用......最後,這完全是關於'完成任務',對吧? – jeroenh 2010-09-17 19:36:55