Foros del Web » Programación para mayores de 30 ;) » .NET »

Generics - Implementar interfaz "dinámica"

Estas en el tema de Generics - Implementar interfaz "dinámica" en el foro de .NET en Foros del Web. Buenas foreros !!! Siento el título, pero no se me ocurria como ponerlo. Tengo la siguiente clase: Código: <Serializable()> Public Class ClsMedicoList Inherits List(Of ClsMedico) ...
  #1 (permalink)  
Antiguo 02/04/2009, 05:16
 
Fecha de Ingreso: junio-2003
Ubicación: Asturias
Mensajes: 2.429
Antigüedad: 20 años, 10 meses
Puntos: 7
Generics - Implementar interfaz "dinámica"

Buenas foreros !!!

Siento el título, pero no se me ocurria como ponerlo.

Tengo la siguiente clase:
Código:
<Serializable()> Public Class ClsMedicoList
    Inherits List(Of ClsMedico)


End Class
Bien, pues he implementado una clase, para ordenar esta lista. Pongo lo más relevante de la clase.

Código:
    Public Class ClsComparadorMedico
        Implements IComparer(Of ClsMedico)

        Public Sub New(ByVal campoFiltro As String, ByVal ordenFiltro As EnumTipoOrden)

            Me._campoFiltro = campoFiltro
            Me._ordenFiltro = ordenFiltro
        End Sub

Public Function Compare(ByVal x As SINSA_ENTITIES.ClsMedico, ByVal y As SINSA_ENTITIES.ClsMedico) As Integer Implements System.Collections.Generic.IComparer(Of SINSA_ENTITIES.ClsMedico).Compare
'Codigo
'Codigo
End Function

Muy bien, ahora para ordenar la lista, lo tengo facil, hago lo siguiente y me la ordena perfecto:

Código:
Me.ListaMedicos.Sort(New HerramientasPresentacion.ClsComparadorMedico("NombrePropiedadDeLaClase", Me.DireccionOrdenacion))

LA PREGUNTA DEL MILLÓN:
¿Como puedo hacer, para que ClsComparadorMedico, en vez de solo recibir elementos de ClsMedico, pueda ser cualquier otro tipo de objeto?


Lo que quiero es, que si tengo otro tipo de Lista, por ejemplo:
Código:
<Serializable()> Public Class ClsCocheList
    Inherits List(Of ClsCoche)

End Class
Pueda llamar también a la misma ordenación.
Código:
Me.ListaCoches.Sort(New HerramientasPresentacion.ClsComparadorMedico("NombrePropiedadDeLaClase", Me.DireccionOrdenacion))

En fin, espero haberme explicado y que puedan ayudarme... lo que quiero es cambair ese implements y la function Compare, para que reciba tipos genéricos, ya que con Object, no me está funcionando...
__________________
Charlie.

Última edición por chcma; 02/04/2009 a las 05:24
  #2 (permalink)  
Antiguo 02/04/2009, 06:44
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Generics - Implementar interfaz "dinámica"

que onda charlie, porque no usar una interfaz propia algo como

IColeccionOrdenable y que en vez de

Public Class ClsComparadorMedico
Implements IComparer(Of ClsMedico)

tengas

Public Class ClsComparadorMedico
Implements IComparer(Of IColeccionOrdenable)

y que cada una de tus clase s CslColeccionCoche o CslColeccionPersona implemente la interfaz IColeccionOrdenable.
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #3 (permalink)  
Antiguo 02/04/2009, 07:04
 
Fecha de Ingreso: junio-2003
Ubicación: Asturias
Mensajes: 2.429
Antigüedad: 20 años, 10 meses
Puntos: 7
Respuesta: Generics - Implementar interfaz "dinámica"

Mmmm, bueno, la verdad que no lo había pensado.

Pero bueno, lo he resuelto de esta manera, os muestro la clase completa por a quien le interese, y a ti Peterpay te invito a que me des sugerencias de la clase, jejeje


Código:
Namespace HerramientasPresentacion


    ''' <summary>
    ''' Clase que realiza la ordenación de los elementos de una lista, según la propiedad enviada y según el orden indicado
    ''' </summary>
    ''' <remarks></remarks>
    Public Class ClsComparador

        Private _campoFiltro As String
        Private _ordenFiltro As EnumTipoOrden

        Private Sub New()
        End Sub

        ''' <summary>
        ''' Constructor con el que se creará la instancia de ordenación.
        ''' </summary>
        ''' <param name="campoFiltro">Nombre de la propiedad del objeto, por la cual se quiere realizar la ordenación.</param>
        ''' <param name="ordenFiltro">Orden que se quiere realizar en la ordenación</param>
        ''' <remarks></remarks>
        Public Sub New(ByVal campoFiltro As String, ByVal ordenFiltro As EnumTipoOrden)

            Me._campoFiltro = campoFiltro
            Me._ordenFiltro = ordenFiltro
        End Sub

        Public Function Comparer(Of T)(ByVal x As T, ByVal y As T) As Integer

            Dim strDatosPropiedadX As DatosPropiedad = GetValorPropiedad(x, Me._campoFiltro)
            Dim strDatosPropiedadY As DatosPropiedad = GetValorPropiedad(y, Me._campoFiltro)

            'SI ES DE TIPO CADENA
            If (strDatosPropiedadX.EsCadena) Then

                Dim valorPrimerPatron As String = strDatosPropiedadX.ValorPropiedad.Trim()
                Dim valorSegundoPatron As String = strDatosPropiedadY.ValorPropiedad.Trim()

                'REALIZO LA COMPROBACION
                If (Me._ordenFiltro = EnumTipoOrden.Desc) Then

                    Return valorPrimerPatron.ToLower().CompareTo(valorSegundoPatron.ToLower)
                Else

                    Return valorSegundoPatron.ToLower().CompareTo(valorPrimerPatron.ToLower)
                End If
            End If


            'SI ES DE TIPO NUMERO
            If (Not strDatosPropiedadX.EsCadena) Then

                Dim valorPrimerPatron As String = strDatosPropiedadX.ValorPropiedad
                Dim valorSegundoPatron As String = strDatosPropiedadY.ValorPropiedad

                If (Me._ordenFiltro = EnumTipoOrden.Desc) Then

                    Return valorPrimerPatron - valorSegundoPatron
                Else

                    Return valorPrimerPatron + valorSegundoPatron
                End If
            End If
        End Function


        Private Function GetValorPropiedad(ByVal objObjeto As Object, ByVal nombrePropiedad As String) As DatosPropiedad

            Dim strDatosPropiedad As New DatosPropiedad
            Dim arrayPropiedades() As String = nombrePropiedad.Split("."c)

            If (arrayPropiedades.Length > 1) Then

                Dim objPropiedad As Object = (objObjeto.GetType().GetProperty(arrayPropiedades(0)).GetValue(objObjeto, Nothing))
                If ((objPropiedad.GetType().GetProperty(arrayPropiedades(1)).GetValue(objPropiedad, Nothing)) IsNot Nothing) Then

                    strDatosPropiedad.ValorPropiedad = (objPropiedad.GetType().GetProperty(arrayPropiedades(1)).GetValue(objPropiedad, Nothing)).ToString().ToLower()
                End If
                strDatosPropiedad.EsCadena = (objPropiedad.GetType().GetProperty(arrayPropiedades(1)).PropertyType.ToString() = "System.String")
            Else

                strDatosPropiedad.ValorPropiedad = (objObjeto.GetType().GetProperty(arrayPropiedades(0)).GetValue(objObjeto, Nothing)).ToString().ToLower()
                strDatosPropiedad.EsCadena = (objObjeto.GetType().GetProperty(arrayPropiedades(0)).PropertyType.ToString() = "System.String")
            End If

            Return strDatosPropiedad

        End Function

        Private Structure DatosPropiedad

            Private _ValorPropiedad As String
            Private _EsCadena As Boolean

            Public Property ValorPropiedad()
                Get

                    If (_ValorPropiedad Is Nothing) Then

                        Return String.Empty
                    End If
                    Return Me._ValorPropiedad
                End Get
                Set(ByVal value)

                    Me._ValorPropiedad = value
                End Set
            End Property
            Public Property EsCadena() As Boolean
                Get

                    Return Me._EsCadena
                End Get
                Set(ByVal value As Boolean)

                    Me._EsCadena = value
                End Set
            End Property
        End Structure
    End Class

    Public Enum EnumTipoOrden
        Asc = 0
        Desc = 1
    End Enum

End Namespace
USO:
Código:
Me.ListaMedicos.Sort(AddressOf New HerramientasPresentacion.ClsComparador("NombreMedico", EnumTipoOrden.Asc).Comparer)
Saludos, y gracias.

Pd.: En cuant tenga tiempo también voy a probar lo que me has comentado de la interfaz, haber si soy capaz de hacerlo funcionar asi, aun que, creo que asi, tampoco esta mal, ¿No crees?
__________________
Charlie.
  #4 (permalink)  
Antiguo 02/04/2009, 07:24
Avatar de Peterpay
Colaborador
 
Fecha de Ingreso: septiembre-2007
Ubicación: San Francisco, United States
Mensajes: 3.858
Antigüedad: 16 años, 8 meses
Puntos: 87
Respuesta: Generics - Implementar interfaz "dinámica"

no no esta mal , lo importante es solucionar la problematica el como, siempre es mejorable o empeorable jajaja.

el usar reflection es la constante.
__________________
Curso WF4
http://cursos.gurudotnet.com/ DF
Aprende HTML5
  #5 (permalink)  
Antiguo 02/04/2009, 07:33
 
Fecha de Ingreso: junio-2003
Ubicación: Asturias
Mensajes: 2.429
Antigüedad: 20 años, 10 meses
Puntos: 7
Respuesta: Generics - Implementar interfaz "dinámica"

jejeje, bueno, falta optimizarla en un par de aspectos, por ejemplo en las propiedades a buscar, solo admite una profundidad de dos. Es decir, si una propiedad es un objeto, y queremos ordenar por un campo de ese objeto, lo hace sin problema. Pero si esa propiedad es a su vez, otro objeto... ya no funcionaría.

Es decir, se puede buscar por (Siendo objMedico el objeto principal):
objMedico.NombreMedico
objMedico.Hospital.NombreHospital

Pero fallaraía al hacer algo como:
objCoche.Motor.Fabricante.NombreFabricante

Pero bueno... almenos es una Beta bastante utilizable, jejeje, espero a alguien le sirva para el futuro.

Nos vemos !!!
__________________
Charlie.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 23:55.