VB.NET: método de extensión imposible de usar en la instancia System.Object
extension-methods late-binding (6)
Claro que puedes, aunque es posible que quieras ser cuidadoso con lo que haces aquí para no saturar cada objeto. Un método de extensión que me gusta usar para Object es un método llamado IsIn () que funciona de forma similar a la instrucción SQL IN (). Es agradable decir cosas como:
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
EDITAR -
Se agregó la implementación del método de extensión IsIn () a continuación para ayudar al comentarista.
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
¿Puedo hacer un método de extensión para todas las subclases de System.Object
(todo)?
Ejemplo:
<Extension>
Public Function MyExtension(value As Object) As Object
Return value
End Function
Las funciones anteriores no funcionarán para la instancia del objeto:
Dim myObj1 As New Object()
Dim myObj2 = myObj1.MyExtension()
El compilador no lo acepta, ¿está el problema en mi computadora? :)
ACTUALIZAR
El problema parece ocurrir solo en VB, donde los miembros del objeto son buscados por reflexión ( late-bound ).
ACTUALIZAR DESPUÉS DE CONTESTAR
FYI, como vb tiene la ventaja de que C # no es así, los miembros de los módulos importados se importan al alcance global, por lo que aún puede usar estas funciones sin su envoltorio:
Dim myObj2 = MyExtension(myObj1)
No puede escribir directamente un método de extensión para Object, pero al usar genéricos puede lograr el mismo resultado:
<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
Tenga en cuenta que puede llamar esto como un método de extensión en todo, excepto en las cosas que se declaran que tienen el tipo Objeto. Para ellos, tienes que llamarlo directamente (a prueba de tontos) o llamar a través de un casting (que podría fallar, ya que no hay una interfaz única, tan un tanto arriesgada).
Parece que no apoyar los métodos de extensión en Object fue una decisión de diseño en VB.
Como resultado, la única forma en que podíamos evitar que los métodos de extensión rompieran por completo el código enlazado tardío existente era evitar que se usen en cualquier elemento escrito como objeto.
Si hace demasiadas extensiones en la inteligencia del objeto puede ser menos útil, pero es perfectamente válido.
Aquí hay un ejemplo de un método de extensión en el objeto para la información del objeto:
http://www.developer.com/net/csharp/article.php/3718806/NET-Tip-Using-Extension-Methods.htm
Vea esta pregunta que hice hace un tiempo . Básicamente, puede extender Object
en VB.NET si lo desea; pero por razones de compatibilidad con versiones anteriores, ninguna variable declarada como Object
podrá usar su método de extensión. Esto se debe a que VB.NET admite la vinculación tardía en Object
, por lo que se ignorará un intento de acceder a un método de extensión a favor de intentar encontrar un método del mismo nombre a partir del tipo del objeto en cuestión.
Así que tome este método de extensión, por ejemplo:
<Extension()>
Public Sub Dump(ByVal obj As Object)
Console.WriteLine(obj)
End Sub
Este método de extensión podría usarse aquí:
'' 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()
Pero no aquí:
'' 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()
Pregúntese por qué los métodos de extensión no funcionan en variables dynamic
en C #, y se dará cuenta de que la explicación es la misma.
La respuesta de jmoreno no se puede usar con Option Strict On
- arroja un error:
BC30512 Opción Estricto Impide conversiones implícitas de ''Objeto'' a ''Entero''.
Necesita un cambio de contexto de la clase al módulo de extensión:
Dim text1 As String = MyExtModule.NullSafeToString(DataGridView1.Rows(0).Cells(0).Value)