2010-07-12 3 views
34

Kann ich eine Extension-Methode für alle Unterklassen von System.Object (alles) machen?VB.NET: unmöglich zu verwenden Extension-Methode auf System.Object-Instanz

Beispiel:

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

Die oben genannten Funktionen nicht für Objektinstanz arbeiten:

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

Der Compiler nicht akzeptiert es, das Problem in meinem Computer? :)

UPDATE
Das Problem scheint nur in VB auftreten, in denen die Mitglieder des Objekts werden durch Reflexion sah-up (late-bound).

UPDATE NACH
FYI BEANTWORTET, als vb einen Vorteil, dass C# fehlt hat das heißt, die Mitglieder der importierten Module werden auf den globalen Bereich importiert, so dass Sie immer noch diese Funktionen ohne ihre Wrapper verwenden können:

Dim myObj2 = MyExtension(myObj1) 

Antwort

8

Sie können nicht direkt eine Erweiterungsmethode für Objekt schreiben, aber die Verwendung von Generika können Sie das gleiche Ergebnis erzielen:

<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 

Beachten Sie, dass dies als eine Erweiterungsmethode auf alles außer Dinge nennen die mit dem Typ Object deklariert sind. Für diese muss man entweder direkt (narrensicher) anrufen oder per Casting (was fehlschlagen könnte, da es keine universelle Schnittstelle gibt, also etwas chance).

-1

Sicher können Sie, obwohl Sie vielleicht sparsam sein wollen, was Sie hier tun, um nicht jedes Objekt zu verstopfen. Eine Erweiterungsmethode, die ich gerne für Object verwende, ist eine Methode namens IsIn(), die ähnlich wie die SQL IN() -Anweisung funktioniert. Es ist schön, Dinge zu sagen wie:

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 

EDIT -

Added Implementierung von isin() Erweiterungsmethode unter Kommentator zu helfen.

+2

Sie diesen Code testen Haben? Die dritte Zeile (someObj) funktioniert nicht für mich. – Shimmy

+0

Ja, das funktioniert für mich. Wie haben Sie Ihre Version der IsIn() Erweiterungsmethode geschrieben? Ich habe meinen Beitrag bearbeitet, um meine Implementierung zu integrieren, um Ihnen zu helfen. – mattmc3

+4

Wenn Sie 'someObj' als' Objekt' in Ihren Code eingegeben haben, sollte dies definitiv * nicht * für Sie funktionieren. –

36

Es scheint, wie nicht Erweiterungsmethoden auf Objekt unterstützt eine Design-Entscheidung in VB wurde.

As a result, the only way we could prevent extension methods from completely breaking existing late bound code was to prevent them from being used on anything typed as object.

http://blogs.msdn.com/b/vbteam/archive/2007/01/24/extension-methods-and-late-binding-extension-methods-part-4.aspx

+1

Antwort mit accpeded für das Bereitstellen von Microsoft-Quelllink. – Shimmy

12

Siehe this question I asked some time ago. Grundsätzlich können Sie Object in VB.NET erweitern, wenn Sie möchten; Aus Gründen der Abwärtskompatibilität kann keine Variable deklariert als Object Ihre Erweiterungsmethode verwenden. Dies liegt daran, dass VB.NET die späte Bindung an Object unterstützt. Daher wird ein Versuch, auf eine Erweiterungsmethode zuzugreifen, ignoriert, um zu versuchen, eine Methode desselben Namens aus dem Typ des betreffenden Objekts zu finden.

nehmen also diese Erweiterung Methode, zum Beispiel:

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

Diese Erweiterung Methode, die hier verwendet werden könnte:

' 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() 

Aber nicht hier:

' 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() 

sich fragen, warum Erweiterung Methoden funktionieren nicht auf dynamic Variablen in C#, und Sie werden feststellen, die Erklärung ist das Gleiche.

1

jmoreno's answerkann nicht mit Option Strict On verwendet werden - es wirft Fehler:

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

Es braucht Kontextwechsel von Klasse zu Erweiterungsmodul:

Dim text1 As String = MyExtModule.NullSafeToString(DataGridView1.Rows(0).Cells(0).Value) 
Verwandte Themen