2010-07-12 100 views
34

我可以爲所有System.Object(所有)的子類創建擴展方法嗎?VB.NET:不可能在System.Object實例上使用擴展方法

例子:

<Extension> 
Public Function MyExtension(value As Object) As Object 
    Return value 
End Function 

上述功能不會爲對象實例的工作:

Dim myObj1 As New Object() 
Dim myObj2 = myObj1.MyExtension() 

編譯器不接受它,是在我的電腦問題? :)

UPDATE
這個問題似乎只發生在VB,其中對象的成員被查找到的反射(late-bound)。

更新後ANSWERED
僅供參考,如VB的優點是,C#缺少也就是說,導入模塊的成員導入到全球範圍,所以你仍然可以使用這個功能,而它們的包裝:

Dim myObj2 = MyExtension(myObj1) 

回答

8

您不能直接寫對象的擴展方法,但是使用泛型,你可以達到同樣的效果:

<Extension()> 
Public Function NullSafeToString(Of T)(this As T) As String 
    If this is Nothing Then 
     Return String.Empty 
    End If 
    Return this.ToString() 
End Function 

請注意,您可以在一切稱此爲一個擴展方法除了東西聲明爲具有Object類型。對於那些,你必須直接調用它(傻瓜證明)或通過鑄造調用(這可能會失敗,因爲沒有univesal接口,所以有點chancy)。

-1

當然你可以,雖然你可能想保留你在這裏做的事情,以免混淆每一個對象。我喜歡用於Object的擴展方法是一種稱爲IsIn()的方法,其功能類似於SQL IN()語句。這是很好的說這樣的話:

If someString.IsIn("a", "b", "c") Then 
    DoSomething() 
Else If someInt.IsIn(1, 2, 3) Then 
    DoSomethingElse() 
Else If someObj.IsIn(1, "q", #7/1/2010#) Then 
    DoSomethingTheThirdWay() 
End If 

編輯 -

新增實施伊辛的()以下的擴展方法幫助提意見。

Imports System.Runtime.CompilerServices 

Public Module ObjectExtensions 
    <Extension()> 
    Public Function IsIn(obj As Object, ParamArray values() As Object) As Boolean 
    For Each val As Object In values 
     If val.Equals(obj) Then Return True 
    Next 
    Return False 
    End Function 
End Module 
+2

你測試的代碼? 第三行(someObj)不適用於我。 – Shimmy 2010-07-12 12:32:25

+0

是的,這對我有用。你是怎麼編寫你的IsIn()擴展方法的版本的?我編輯了我的文章,包括我的實施,以幫助你。 – mattmc3 2010-07-12 12:48:12

+4

如果您在代碼中輸入了'someObj'作爲'Ob​​ject',那麼這絕對不應該爲您工作。 – 2010-07-12 13:09:40

12

this question I asked some time ago。基本上,你可以可以擴展Object在VB.NET如果你想;但出於向後兼容性的原因,沒有變量宣稱爲,因爲Object將能夠使用您的擴展方法。這是因爲VB.NET支持Object上的後期綁定,所以嘗試訪問擴展方法將被忽略,以便試圖從相關對象的類型中找到同名的方法。

所以採取這種擴展方法,例如:

<Extension()> 
Public Sub Dump(ByVal obj As Object) 
    Console.WriteLine(obj) 
End Sub 

這個擴展的方法可以用在這裏:

' Note: here we are calling the Dump extension method on a variable ' 
' typed as String, which works because String (like all classes) ' 
' inherits from Object. ' 
Dim str As String = "Hello!" 
str.Dump() 

但不是在這裏:

' Here we attempt to call Dump on a variable typed as Object; but ' 
' this will not work since late binding is a feature that came before ' 
' extension methods. ' 
Dim obj As New Object 
obj.Dump() 

問自己,爲什麼延期方法不適用於C#中的dynamic變量,你會意識到解釋是一樣。

1

jmoreno's answer不能與Option Strict On使用 - 它拋出錯誤:

BC30512 Option Strict On disallows implicit conversions from 'Object' to 'Integer'.

它需要從類上下文切換到擴展模塊:

Dim text1 As String = MyExtModule.NullSafeToString(DataGridView1.Rows(0).Cells(0).Value) 
相關問題