2012-03-07 7 views
7

Cuando se trabaja con MVVM y Prisma me encuentro haciendo una gran cantidad de fundición, como la mayoría de los parámetros son interfaces¿Cuál es el costo de los parámetros de colada

Ex

public void AddCrSubSystemsToPlant(IPlantItem plantItm, CRArticleItem crItm) 
     { 

      OSiteSubSystem itm = (OSiteSubSystem)crItm; 
      itm.PartData.Order = ((OSiteEquipment)plantItm).SubSystems.Count() + 1; 

      ((OSiteEquipment)plantItm).SubSystems.Add(itm); 

     } 

o

public void DeletePart(IPlantItem plantItem) 
     { 
      IEnumerable<IPlantItem> itmParent = GetParentPartByObjectId(_siteDocument, plantItem); 

      if (plantItem is OSiteEquipment) 
      ((ObservableCollection<OSiteEquipment>)itmParent).Remove((OSiteEquipment)plantItem); 

      if (plantItem is OSiteSubSystem) 
       ((ObservableCollection<OSiteSubSystem>)itmParent).Remove((OSiteSubSystem)plantItem); 

      if (plantItem is OSiteComponent) 
       ((ObservableCollection<OSiteComponent>)itmParent).Remove((OSiteComponent)plantItem); 
     } 

Mi La pregunta es, ¿cuál es el costo involucrado? ¿Son estas operaciones costosas para la memoria o la CPU, en caso de que se eviten?

¿Alguna opinión?

+10

¿Por qué necesita todos estos moldes? ¿Sus interfaces no exponen las operaciones requeridas? ¿Si no, porque no? – Oded

+1

Probablemente podrías simular algunos casos de prueba con y sin casting y medir el rendimiento. No creo que ningún elenco individual tenga mucho éxito, pero depende de la frecuencia con que lo hagas. –

+0

Consulte esta respuesta relacionada: http://stackoverflow.com/a/9366456/414076 –

Respuesta

7

Creo que la pregunta más importante es ¿por qué haces tanto de fundición?

En el primer ejemplo:
¿Por qué es el primer parámetro de tipo IPlantItem Si se mantiene convierte para que OSiteEquipment? Lo mismo puede decirse sobre el segundo parámetro.

En el segundo ejemplo:
¿Por qué GetParentPArtByObjectId devuelve un IEnumerable<IPlantItem>? Si devolviera un ICollection<IPlantItem>, no tendría que realizar el envío al ObservableCollection<T>. ObservableCollection<T> hereda de Collection<T> que implementa ICollection<T> y ICollection. Debería poder eliminar el elemento de la colección sin saber siquiera su tipo.

Ahora algunos consejos.
No arroje el mismo objeto varias veces.
No haga esto:

if (obj is IPlantItem) 
    ((IPlantItem)obj).DoSomething(); 

haga esto en lugar

IPlantItem plant = obj as IPlantItem; 
if (plant != null) 
    plant.DoSomething(); 

tipos de uso base siempre que sea posible.Esto te evitará tener que lanzar mucho. Como se indicó anteriormente, no realice el envío a ObserableCollection<T> para llamar a un método en ICollection

Use genéricos. Si necesita una lógica específica de tipo, cree una clase base abstracta (o solo una interfaz si no necesita ninguna lógica compartida) con un parámetro genérico. Luego realice implementaciones de esa clase para cada una de las implementaciones de la interfaz. Los métodos también pueden ser genéricos. Puedo volver a escribir el segundo ejemplo como

public void DeletePart<TPlantItem>(TPlantItem plantItem) 
    where TPlantItem : IPlantItem 
{ 
    IEnumerable<TPlantItem> itmParent = GetParentPartByObjectId(_siteDocument, plantItem); 
    ((ObservableCollection<TPlantItem>)itmParent).Remove(plantItem); 
} 
+0

Buena suerte con las pruebas unitarias cuando la implementación requiere una implementación real y no el comportamiento de una interfaz. – weismat

+0

Por eso recomendé cambiar los tipos de parámetros en lugar de las clases/interfaces abstractas genéricas y de conversión con implementaciones específicas de tipo. – cadrell0

+0

Aunque le dio al OP lo que necesitaba, creo que darle lo que quería ("¿Cuál es el costo del casting?") Al menos en breve sería bueno. – svick

0

Este artículo podría arrojar alguna luz sobre la forma de fundición afecta al rendimiento

http://www.codeproject.com/Articles/8052/Type-casting-impact-over-execution-performance-in

Éstos son algunos consejos generales para la optimización de sus programas basados ​​en los resultados obtenidos en los apartados anteriores:

  • Las conversiones de tipo numérico suelen ser costosas, sacarlas de los bucles y las funciones recursivas y usar los mismos tipos numéricos cuando posible.

  • Downcasting es un gran invento pero los controles de tipo implicados tienen un gran impacto en el rendimiento de ejecución, comprueba los tipos de objetos de bucles y funciones recursivas, y utiliza el operador "as" en ellos.

  • Upcasting es barato !, úselo en todas partes que necesite.

  • Crea operadores de conversión ligeros para hacer moldes personalizados más rápido. Herramientas utilizadas
+0

Tenga en cuenta que el artículo tiene casi 8 años. –

+0

He descubierto que la mayoría de estos principios y resultados se mantienen aunque las cifras pueden estar desactualizadas. – Ani

1

uso

 ((System.Collections.IList)itmParent).Remove(plantItem); 

en lugar de

 if (plantItem is OSiteEquipment) 
     ((ObservableCollection<OSiteEquipment>)itmParent).Remove((OSiteEquipment)plantItem); 

     if (plantItem is OSiteSubSystem) 
      ((ObservableCollection<OSiteSubSystem>)itmParent).Remove((OSiteSubSystem)plantItem); 

     if (plantItem is OSiteComponent) 
      ((ObservableCollection<OSiteComponent>)itmParent).Remove((OSiteComponent)plantItem); 
Cuestiones relacionadas