views:

145

answers:

6

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)
A: 

You can make extension method for all types. The above function is valid, but if you want to do any type specific task, you first have to cast the object into that type and then do those operations. So there is not a big deal you can do in making extension methods for object. However it introduces overhead of casting if you wish to do some type specific tasks.

cornerback84
It's valid, but it doesn't work try and see :)
Shimmy
That maybe because you are not doing anything in that function. The extension method is called when you use it. I have debugged it
cornerback84
hmnn. strange. I can do that in C# and the documentation doesn't say anything about this. VB do not complain about methods call but gives an exception during execution
cornerback84
@cornerback84 Your first comment above that it doesn't work because it doesn't do anything is essentially refuted. about your second comment, exactly, cuz VB is supposed to parse Object members during runtime, and that's actually the huge advantage of VB, it's extremely useful when working with COM or other dynamic object, it has been characterizing VB since ever. That one of the things I can't live without vb. It's like the C# dynamic word, but built in the language. no extensions no nuts
Shimmy
A: 

You can make extension methods for objects. I've done it in the past but some people recommend against it for reasons I'm not sure of.

Matthew Steeples
Reread my question please. I provided example for what I mean on object.
Shimmy
I apologise, I use C# rather than VB and I hadn't realised the two were different
Matthew Steeples
+1  A: 

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
mattmc3
Did you test this code?The third line (someObj) doesn't work for me.
Shimmy
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.
mattmc3
If you typed `someObj` as `Object` in your code, then this definitely should *not* work for you.
Dan Tao
Yes, in my example you cannot declare `someObj` as the generic System.Object type. Sorry I didn't make that clearer.
mattmc3
A: 

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

Andrew
My problem is VB specific.
Shimmy
+9  A: 

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.

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

jdot
Accpeted answer for providing Microsoft source link.
Shimmy
+3  A: 

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.

Dan Tao