.net vb.net object extension-methods late-binding

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




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)