39

Can I make an Extension method for all the subclasses of System.Object (everything)?

Example:

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

The above functions won't work for object instance:

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

The compiler does not accept it, is the problem in my computer? :)

UPDATE
The problem seems to occur only in VB, where members of object are looked-up by reflection (late-bound).

UPDATE AFTER ANSWERED
FYI, as vb has an advantage that C# lacks that is, members of imported Modules are imported to the global scope so you can still use this functions without their wrapper:

Dim myObj2 = MyExtension(myObj1)
1
  • 1) It is now possible in C# with the using static <namespace.type> syntax to import members into the current scope. 2) The problem seems to occur only in VB, where members of object are looked-up by reflection. Isn't that only true if Option Strict Off? Commented Aug 4, 2020 at 7:15

6 Answers 6

47

It seems like not supporting Extension methods on Object was a design decision in VB.

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.

Link

Sign up to request clarification or add additional context in comments.

1 Comment

Accpeted answer for providing Microsoft source link.
14

See this question I asked some time ago. Basically, you can extend Object in VB.NET if you want; but for backwards compatibility reasons, no variable declared as Object will be able to use your extension method. This is because VB.NET supports late binding on Object, so an attempt to access an extension method will be ignored in favor of trying to find a method of the same name from the type of the object in question.

So take this extension method, for example:

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

This extension method could be used here:

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

But not here:

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

Ask yourself why extension methods don't work on dynamic variables in C#, and you'll realize the explanation is the same.

Comments

13

You can not directly write an extension method for Object, but using generics you can achieve the same result:

<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

Note that you can call this as an extension method on everything except things that are declared to have the type Object. For those, you have to either call it directly (full proof) or call via casting (which could fail, as there is no univesal interface, so somewhat chancy).

2 Comments

What is the difference with the extension proposed by the OP? As far as I understand and tested, both result in the same behaviour and will work/not work under the same contexts as well. What am I missing?
@Ama: one of the differences is that you can have it return the same type of object that you passed in, without having to add type coercion to your calling location. My example returned a string, but you could use a method that returns the lesser of two values or a defined default value.
1

jmoreno's answer cannot be used with Option Strict On – it throws error:

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

It needs context switch from class to extension module:

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

Comments

0

Sure you can, though you might want to be sparing about what you do here so as not to clutter every object. An extension method I like using for Object is a method called IsIn() that functions similarly to the SQL IN() statement. It's nice to say things like:

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 implementation of IsIn() extension method below to help commenter.

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

6 Comments

Did you test this code? The third line (someObj) doesn't work for me.
Yes, this works for me. How did you write your version of the IsIn() extension method? I've edited my post to include my implementation to help you out.
If you typed someObj as Object in your code, then this definitely should not work for you.
Yes, in my example you cannot declare someObj as the generic System.Object type. Sorry I didn't make that clearer.
It's bizarre to me that this answer has been down voted so badly. This is one of my favorite extension methods, gives an example of how to do an extension method on Object, and answers the question. #SOFailDownvoteFail.
|
-5

If you do too many extensions on object intellisence might become less useful, but it's perfectly valid.

Here's an example of an extension method on object for object information:

http://www.developer.com/net/csharp/article.php/3718806/NET-Tip-Using-Extension-Methods.htm

1 Comment

The linked article refers to extension methods in C#, not VB.NET; as such it's irrelevant to the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.