2017-10-23 1 views
1

私はC#プログラミングの新機能であり、以下のシナリオがあるLazy Load&Typeは可能ですか?単一反復でオブジェクトをキャストしますか?

私はいくつかのオブジェクトのプロパティに基づいて反復処理したい、IEnumerableをを返すAPIを使用しています:私はフィルターで返されたオブジェクトを型キャストすることはできませんですので

IEnumerable<objects> listOfObjects = filter.getItems(id); 
List<CustomObject> sortedList = new List<CustomObject>(); 
      foreach (CustomObject obj in listOfObjects) 
      { 
       obj.Load(Load.Expanded); 
       sortedList.Add(obj); 
      } 
foreach (CustomObject custObj in sortedList.OrderByDescending(c => c.RevisionDate)) 
      { 
       // business logic 
      } 

は、私は上記のすべてを行う必要がありますクエリ。また、フィルタクエリから返されたオブジェクトはロードされません。つまり、最初のforeachループを実行しないと、2番目のforeachのRevisionDate値はnullになります。

このシナリオを処理するより良い方法があるのだろうかと思っていますが、これらの数の行を1つのループで削除することはできますか? Selectその中obj.Loadのような副作用を持っているものを持つ(Selectのような使用法は、通常は落胆し、非常に良い方法ではありませんされていることを

foreach (var custObj in listOfObjects 
         .Cast<CustomObject>() 
         .Select(obj => {obj.Load(); return obj;}) 
         .OrderByDescending(c => c.RevisionDate)) 

注:

+0

uはそれを行う方法が完全に罰金です。 obj状態をロードする副作用がない場合、単純化されている可能性があります。現在のシナリオでは問題ないと思います。 –

+0

最初に、 '.OfType ()'を最初の行の最後に追加するだけで、キャストを行うことができます。第2に、使用しているフレームワークがオブジェクトをロードしない場合、別のフレームワークを使用します。 –

+0

@PeterMorris:いいえ、キャストを行うには '.Cast ()'を使います。 'OfType'を使ってフィルタリングを行います。違う理由は '誤って' listOfObjects'にいくつかの 'NotCustomObject'があると、あなたの問題を隠してしまいます。間違ったオブジェクトを持っているので' Cast'メソッドは例外をスローします。 。 – Chris

答えて

1

あなたがIEnumerableを法Selectを利用することができるはずにも適用することができます。

例は、からです。

hereを参照してください。要するに

、あなたは最初のループを排除するために、このような何かをしたいと思う:

List<CustomObject> sortedList = filter.getItems(id).Select<object, CustomObject>(x => 
      { 
      (CustomObject)x).Load(Load.Expanded); 
      return (CustomObject)x; 
      }); 
+0

あなたのコードは編集上の問題を抱えていると思います(最初の行は削除される可能性があります) 'Load'が実際にオブジェクトを返すというオリジナルのポストからの指示はありません。 'void'戻り型であるかのように使われます。 – Chris

+1

eesh、それは私のところでは醜いものでした。迷惑行を削除し、Loadをvoid returnとして扱うようにラムダを設定するように修正されました。 – JESteph

4

あなたはこのようなものLINQ文でそれを行うことができます)です。

0

Theraは、遅延初期化を処理するように設計されたC#ライブラリのいくつかの特別な構造です。それぞれには、あなたが必要とするより良くても悪いものでもよいいくつかの特質があるかもしれません。

最初はSystem.Lazy<T>クラスです。クラスオーバーヘッドなしでパフォーマンスが向上しています。System.Threading.LazyInitializerには静的メソッドが多数あり、スレッド固有のデータを提供しますSystem.Threading.ThreadLocal<T>Lazy<T>

使い方はシンプルで、代わりにコンストラクタでラムダを渡すの

// Initialize by using default Lazy<T> constructor. The 
// Orders array itself is not created yet. 
Lazy<Orders> _orders = new Lazy<Orders>(); 

// Initialize by invoking a specific constructor on Order which 
// will be used when Value property is accessed 
Lazy<Orders> _orders = new Lazy<Orders>(() => new Orders(100)); 

// Lazy<Orders> will create the array only if displayOrders is 
// which will go through path where _orders.Value is accessed 
if (displayOrders == true) 
{ 
    DisplayOrders(_orders.Value.OrderData); 
} 
else 
{ 
    // Don't waste resources getting order data. 
} 

あなたがCustomObjectにあなたのオブジェクトをキャストラムダを渡すことができます。最良のパフォーマンスを目指す場合は、Linqを避けて、手続き的な方法で実行してください。 Lazy Initialization Microsoft Docs明確にするために私によって変更コメントで、ほぼ直接あなたのコード

+0

あなたの事例をOPの状況に合わせることができますか? 'IEnumerable 'をあなたのLazyクラスにどのような点で変換するのかは分かりません... Ienumerableのオブジェクトがそれぞれレイジーオブジェクトに置き換えられているのですか、 'IEnumerable'全体が' Lazy'に置き換えられますか? 'obj.Load(Load.Expanded)'はいつ呼び出されますか?また、Lazyを導入するのが実際にオブジェクトのそれぞれに対して '.Load'を呼び出すよりも優れているかどうかはわかりません... – Chris

関連する問題