考虑以下扩展方法:
<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中完全按照我的意愿工作,我的第二次尝试是最安全/最有效的方法吗?
答案 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方法实现为常规模块方法而不是扩展方法。