Hola Leandro,

Probablemente haya malinterpretado el problema pero, en el código original, ¿no 
podrías invocar a ApplyFormat<FormatInfo> (sin el typeof)? O sea,

  foreach (FormatInfo format in pivotTableInfo.Format)
  {
      ApplyFormat<FormatInfo>(sheet, pivotTable, format);
  }

Es más, ¿es realmente necesario que ApplyFormat sea genérico si ya se sabe que 
recibe un parámetro de tipo FormatInfo? En el código reformado hay un método 
independiente para clase derivada, pero estos solo "forwardean" al método 
genérico. Aún cuando ApplyFormat<T> fuera invocado con una clase derivada no 
puede hacer uso de sus miembros a menos que en el cuerpo del método también 
existan ifs para cada clase derivada y se haga el cast correspondiente. 
Entonces no me queda claro para que debe existir un método diferente para cada 
una de las clases derivadas. ¿No serviría definirlo de la siguiente forma?

  private void ApplyFormat(Office.Worksheet sheet, 
                             Office.PivotTable pivotTable, FormatInfo format) 
  {
       // llamo a los métodos de FormatInfo
       format.AlgunMetodoDeLaClaseBase();

       // para llamar a los métodos de alguna de sus clases derivadas es 
necesario 
       // un cast, pero el cast sería igualmente necesario con el método 
genérico
       ((ButtonFormatInfo) format).UnMetodoDeButtonFormatInfo();
  }

y entonces el loop sería simplemente

  foreach (FormatInfo format in pivotTableInfo.Format)
  {
      ApplyFormat(sheet, pivotTable, format);
  }


Saludos,

Fernando Tubio

  ----- Original Message ----- 
  From: Leandro Tuttini 
  To: [email protected] 
  Sent: Thursday, May 07, 2009 2:30 PM
  Subject: [puntonet] Generics invocacion generica (utilizando typeof)



        Hola, gracias a todos por las respuestas, fueron de utilidad.

        Modifique la implementacion quedando de esta forma:


        private void ApplyFormat(Office.Worksheet sheet, Office.PivotTable 
pivotTable, ButtonFormatInfo format)
        {
            ApplyFormat<ButtonFormatInfo>(sheet, pivotTable, 
(ButtonFormatInfo)format);
        }

        private void ApplyFormat(Office.Worksheet sheet, Office.PivotTable 
pivotTable, FieldFormatInfo format)
        {
            ApplyFormat<FieldFormatInfo>(sheet, pivotTable, 
(FieldFormatInfo)format);
        }

        private void ApplyFormat(Office.Worksheet sheet, Office.PivotTable 
pivotTable, OriginFormatInfo format)
        {
            ApplyFormat<OriginFormatInfo>(sheet, pivotTable, 
(OriginFormatInfo)format);
        }

        private void ApplyFormat(Office.Worksheet sheet, Office.PivotTable 
pivotTable, BlankFormatInfo format)
        {
            ApplyFormat<BlankFormatInfo>(sheet, pivotTable, 
(BlankFormatInfo)format);
        }


        private void ApplyFormat<T>(Office.Worksheet sheet, Office.PivotTable 
pivotTable, T format) where T : FormatInfo
        {

        }


        Para utilizarlo hago lo siguiente:

        foreach (FormatInfo format in pivotTableInfo.Format)
              ApplyFormat(sheet, pivotTable, format);


        Y la verdad quedo bastante bien, por supuesto agregue todo en una 
#region y quedo lindo.
        Al menos me libre del interminable if.

        gracias

        --- El jue 7-may-09, Daniel Calvin <[email protected]> escribió:

          De: Daniel Calvin <[email protected]>
          Asunto: [puntonet] Generics invocacion generica (utilizando typeof)
          Para: [email protected]
          Fecha: jueves, 7 de mayo de 2009, 11:59 am


          Hola Leandro

          Tal vez me equivoque, pero no me parace una buena forma de usar 
generics.

          Te doy mi opinion hacer:

          if (format is Mapping.PivotTableInfo.ButtonFormatInfo)
                  ApplyFormat<ButtonFormatInfo>(sheet, pivotTable, 
(ButtonFormatInfo)format);

          no es una buena práctica

          Se me ocurren otras opciones:
          en vez de :

          private void ApplyFormat<T>(Office.Worksheet sheet, Office.PivotTable 
pivotTable, T format) where T : FormatInfo
          {
          }


          hacer:

          private void ApplyFormat(Office.Worksheet sheet, Office.PivotTable 
pivotTable,  FieldFormatInfo format)  
          {
          }



          private void ApplyFormat(Office.Worksheet sheet, Office.PivotTable 
pivotTable,  ButtonFormatInfo format)  
          {
          }



          private void ApplyFormat(Office.Worksheet sheet, Office.PivotTable 
pivotTable,  FormatInfo format)  
          {
          }



          Tener una firma por cada posible FormatInfo y uno que reciba el tipo 
base para los que no requieren particularidades.

          Me parece lo mas sano.

          Yo al menos no usaría generics para esto o al menos de esa manera.

          En la práctica preguntar por un type es comprar problemas....

          Saludos

          Daniel Calvin



          El 7 de mayo de 2009 10:55, Leandro Tuttini 
<[email protected]> escribió:

                  Hola,

                  Les planteo la siguiente situacion.

                  Tengo las siguientes clases:

                  public abstract class FormatInfo
                  {
                  }

                  public class FieldFormatInfo : FormatInfo
                  {
                  }

                  public class ButtonFormatInfo : FormatInfo
                  {
                  }

                  public class OriginFormatInfo : FormatInfo
                  {
                  }

                  public class BlankFormatInfo : FormatInfo
                  {
                  }


                  Y la siguiente implementacion:


                  foreach (FormatInfo format in pivotTableInfo.Format)
                  {
                      //ApplyFormat<typeof(format)>(sheet, pivotTable, format);

                      if (format is Mapping.PivotTableInfo.ButtonFormatInfo)
                          ApplyFormat<ButtonFormatInfo>(sheet, pivotTable, 
(ButtonFormatInfo)format);
                      else if (format is Mapping.PivotTableInfo.FieldFormatInfo)
                          ApplyFormat<FieldFormatInfo>(sheet, pivotTable, 
(FieldFormatInfo)format);
                      else if (format is 
Mapping.PivotTableInfo.OriginFormatInfo)
                          ApplyFormat<OriginFormatInfo>(sheet, pivotTable, 
(OriginFormatInfo)format);
                      else if (format is Mapping.PivotTableInfo.BlankFormatInfo)
                          ApplyFormat<BlankFormatInfo>(sheet, pivotTable, 
(BlankFormatInfo)format);

                  }


                  pivotTableInfo.Format, es una propiedad del tipo:

                  public List<FormatInfo> Format { get; set; }


                  Y ApplyFormat() es un metodo:

                  private void ApplyFormat<T>(Office.Worksheet sheet, 
Office.PivotTable pivotTable, T format) where T : FormatInfo
                  {
                  }



                  Como veran funciona sin problema, pero la verdad no queda 
nada agradable a la vista, en realidad yo reduje un poco el ejemplo, hay unos 6 
format mas que hacen el if
                  bastante feo.

                  por eso la cuestion es porque no puedo hacer algo asi:

                  foreach (FormatInfo format in pivotTableInfo.Format)
                  {
                      ApplyFormat<typeof(format)>(sheet, pivotTable, format);
                  }

                  O sea la aplicacion del template seria dinamica.

                  Se puede lograr algo parecido a esto ?, o la unica forma es 
con los if descubriendo el tipo.

                  Saludos 



--------------------------------------------------------------------

            Yahoo! Cocina
            Recetas prácticas y comida saludable
            Visitá http://ar.mujer.yahoo.com/cocina/



          -- 
          Daniel A. Calvin
          Cooperator Team Member
          http://www.cooperator.com.ar
          Microsoft Certified Professional
       


------------------------------------------------------------------------------

  ¡Viví la mejor experiencia en la web!
  Descargá gratis el nuevo Internet Explorer 8
  http://downloads.yahoo.com/ieak8/?l=ar

Responder a