2012-03-07 18 views
7

MVVMとプリズムで作業する場合いただきましたほとんどのパラメータは、インタフェース鋳造パラメータのコストが

public void AddCrSubSystemsToPlant(IPlantItem plantItm, CRArticleItem crItm) 
     { 

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

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

     } 

または

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

マイいるとして、私は、自分自身がキャストをたくさんやって見つけます質問は、費用は何ですか?これらの操作にはコストがかかりますか、CPUを避けてください。

ビューがありますか?

+10

なぜあなたは、これらすべてのキャストが必要なのでしょうか?インターフェイスで必要な操作が公開されていませんか?そうでない場合は、どうしてですか? – Oded

+1

キャストの有無にかかわらず、いくつかのテストケースをモックアップして、パフォーマンスを測定できます。私は個々のキャストはパフォーマンスヒットの多くはないと思いますが、あなたがそれをどれくらい頻繁に行うかによって異なります。 –

+0

関連する答えを見てください:http://stackoverflow.com/a/9366456/414076 –

答えて

7

私はより重要な質問はなぜそんなに鋳造しているのですか?最初の例で


は、なぜあなたはOSiteEquipmentにそれを最初のパラメータの型IPlantItemキャストし続けている場合はどうなりますか?第2パラメータについても同様である。

2番目の例では、
なぜGetParentPArtByObjectIdはIEnumerable<IPlantItem>を返しますか? ICollection<IPlantItem>を返す場合は、ObservableCollection<T>にキャストする必要はありません。 ObservableCollection<T>は、ICollection<T>ICollectionの両方を実装するCollection<T>から継承します。タイプを知らなくてもコレクションからアイテムを削除することができます。

ここでいくつかのアドバイス。
同じオブジェクトを複数回キャストしないでください。
はこれをしないでください。可能な限り

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

が、この代わりに

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

使用ベースタイプを行います。これにより、あなたはあまりにも多くをキャストする必要がなくなります。先に述べたように、方法を呼び出すにはObserableCollection<T>にキャストしないでください。ICollection

ジェネリックを使用してください。タイプ固有のロジックが必要な場合は、抽象基本クラス(または共有ロジックが必要ない場合はインタフェースのみ)を汎用パラメーターで作成します。次に、インタフェースの実装ごとにそのクラスの実装を行います。メソッドも汎用である可能性があります。私は

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

実装に実際の実装が必要で、インタフェースの動作が必要ない場合は、ユニットテストで幸運を祈る。 – weismat

+0

私はキャストの代わりにパラメータ型の変更と、型固有の実装を持つ汎用抽象基本クラス/インタフェースの変更を推奨しました。 – cadrell0

+0

あなたはOPを彼に必要なものを与えても、私は彼に彼が望んでいたものを与えていると思う(「キャスティングのコストはいくらですか?」)。 – svick

0

この記事では、鋳造がパフォーマンスにどのように影響するかについていくつかの光を当てるかもしれません

ここ

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

は、前のセクションで得られた 結果に基づいてプログラムを最適化するためのいくつかの一般的なヒントです:

  • 数値型の変換は通常コストが高く、ループや再帰関数から取り出して同じ数値型を使用します が可能です。

  • ダウンキャスティングは非常に優れていますが、タイプチェックは実行パフォーマンスに大きな影響を与えます。 ループと再帰関数のオブジェクトタイプをチェックし、それらに "as"演算子を使用します。

  • アップキャストは安いですが、どこでも必要な場所で使用してください。

  • カスタムキャストを高速化するための軽量変換演算子を作成します。使用されるツール
+0

記事は約8歳です。 –

+0

私は、これらの原則および結果のほとんどは、数字が古くなっているかもしれないが、保持していることを発見した。 – Ani

1

使用などの第二の例を書き換えることができ

 ((System.Collections.IList)itmParent).Remove(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);