通用扩展

时间:2011-07-21 21:36:31

标签: .net vb.net

我正在尝试创建一个通用的IsEmpty扩展,但是我遇到了专门针对字典的问题:

我创建的功能:

<Extension()> Function IsEmpty(null As DBNull) As Boolean
  Return True
End Function

<Extension()> Function IsEmpty(d As Date) As Boolean
  Return d = New Date
End Function

<Extension()> Function IsEmpty(s As String) As Boolean
  Return s Is Nothing OrElse s.Length = 0
End Function

<Extension()> Function IsEmpty(a As Array) As Boolean
  Return a Is Nothing OrElse a.Length = 0
End Function

<Extension()> Function IsEmpty(collection As ICollection) As Boolean
  Return collection Is Nothing OrElse collection.Count = 0
End Function

<Extension()> Function IsEmpty(Of T)(val As T) As Boolean
  Return False
End Function

就我的目的而言,布尔和数字从不“空”。

问题是字典使用泛型(Of T)(val As T)函数而不是(collection as ICollection)函数。

Dim dict As New Dictionary(Of String,String)
Response.Write(dict.IsEmpty)

输出为“False”

我尝试使用(Of K,V)(集合为ICollection(Of KeyValuePair(Of K,V)))无济于事。

我做错了什么?

3 个答案:

答案 0 :(得分:2)

问题是你的超载:

Function IsEmpty(Of T)(val As T) As Boolean

变得比以下更具体:

Function IsEmpty(collection As ICollection) As Boolean

编译器将首先选择泛型过载,因为它可以将T指定为Dictionary(of String, String),它比ICollection更具体。如果将泛型方法更改为简单地获取对象,则ICollection重载将更具体,并由编译器选择:

Function IsEmpty(val As Object) As Boolean

答案 1 :(得分:1)

尝试更改最后一次重载,以System.Object为参数。我认为这将是你想要的最低优先级。

编译器比ICollection的重载更喜欢当前的那个,因为转换为ICollection将是类型转换。通过采用任何类型,它不被视为类型转换,因此它具有更高的优先级。

答案 2 :(得分:0)

我不认为你正在为VB.Net正确编写扩展方法,对于初学者来说。

修改
好的,看MSDN,您使用的是大多数正确的格式。但是你需要做这样的事情:

Imports System.Runtime.CompilerServices

Module Module1

    Private dict As Dictionary(Of String, String)

    Sub Main()
        If dict.IsEmpty() Then
            Console.WriteLine("We're Empty")
        End If

        Console.ReadLine()
    End Sub

    <Extension()> Function IsEmpty(Of TKey, TVal)(ByRef collection As Dictionary(Of TKey, TVal)) As Boolean
        Return collection Is Nothing OrElse Collection.Count = 0
    End Function

End Module

为了使您的扩展方法正常工作,您需要参数中的ByRef(据我所知,它来自MSDN)。无论如何,上面的例子按原样工作。