klashagelqvist
klashagelqvist

Reputation: 1261

Whats the cost of casting parameters

When working with MVVM and Prism i find myself doing a lot of casting, as most parameters are interfaces

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

        }

or

  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);
        }

My question is , whats the cost involved. Are these operations costly memory or cpu wise, should they be avoided.

Any views?

Upvotes: 7

Views: 511

Answers (3)

Ani
Ani

Reputation: 10906

This article might shed some light on how casting affects performance

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

Here are some general tips for optimizing your programs based on the results obtained in the previous sections:

  • Numeric type conversions are usually expensive, take them out of the loops and recursive functions and use the same numeric types when possible.

  • Downcasting is a great invention but the type checks involved have a great impact on execution performance, check the object types out of loops and recursive functions, and use the "as" operator into them.

  • Upcasting is cheap!, use it everywhere you need.

  • Build lightweight conversion operators to make custom casts faster. Tools used

Upvotes: 0

Serj-Tm
Serj-Tm

Reputation: 16981

use

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

instead of

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

Upvotes: 1

cadrell0
cadrell0

Reputation: 17327

I think the more important question is why are you doing so much casting?

In the first example:
Why is the first parameter type IPlantItem if you keep casting it to OSiteEquipment? The same can be said about the second parameter.

In the second example:
Why does GetParentPArtByObjectId return an IEnumerable<IPlantItem>? If it were to return an ICollection<IPlantItem> you wouldn't have to cast to ObservableCollection<T>. ObservableCollection<T> inherits from Collection<T> which implements both ICollection<T> and ICollection. You should be able to remove the item from the collection without even knowing its type.

Now some advice.
Don't cast the same object multiple times.
Don't do this:

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

Do this instead

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

Use base types whenever possible. This will keep you from needing to cast so much. As previously stated, don't cast to ObserableCollection<T> to call a method on ICollection

Use generics. If you need type specific logic, make an abstract base class(or just an interface if you don't need any shared logic) with a generic parameter. Then make implementations of that class for each of the implementations of the interface. Methods can be generic, too. I can rewrite the second example as

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

Upvotes: 7

Related Questions