VB.NET: impossible to use Extension method on System.Object instance

后端 未结 6 1033
南方客
南方客 2020-12-03 09:49

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

Example:


Public Function MyExtens         


        
相关标签:
6条回答
  • 2020-12-03 10:04

    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.

    0 讨论(0)
  • 2020-12-03 10:14

    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

    0 讨论(0)
  • 2020-12-03 10:18

    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
    
    0 讨论(0)
  • 2020-12-03 10:23

    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

    0 讨论(0)
  • 2020-12-03 10:26

    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)
    
    0 讨论(0)
  • 2020-12-03 10:31

    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).

    0 讨论(0)
提交回复
热议问题