VB.NET通用约束和子类

时间:2010-09-17 18:49:13

标签: vb.net generics

考虑以下扩展方法:

    <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的超类,则除非将subject显式强制转换为超类,否则此扩展将不起作用。有没有办法可以避免这种情况?到目前为止,我能够提出的最好的是:

    <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中完全按照我的意愿工作,我的第二次尝试是最安全/最有效的方法吗?

2 个答案:

答案 0 :(得分:4)

这是通过扩展方法的设计,因为它们在VB中应用。我不确定为什么他们为VB构建不同的扩展,但对于VB,约束TDerived:TBase不存在。不幸的是,如果没有它,你就无法将TDerived转换为TBase,因此IsSatisfiedBy函数失败。供参考:

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

您的第一个实现似乎是唯一可行的实现,这是对VB框架中如何设计Extension方法的限制。

答案 1 :(得分: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编译器说:'扩展方法'Satisfies'具有永远无法满足的类型约束',这很奇怪,因为在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所说,将Satisfies方法实现为常规模块方法而不是扩展方法。