1

ArticleBlogPost、およびの 3 つの主要なタイプの「オンライン ニュース出版物」を含むサイトを構築していますColumnPost。サイト全体に、これらのリストを出力するさまざまなコントロールがあり、一緒に混合したり、混合したりしません。したがって、多くのコントロールには記事のリストがあり、他のコントロールにはブログ投稿とコラム投稿のリストがあります。いくつかの場所では、記事、ブログ投稿、およびコラム投稿のリストさえ持っています。そこで、 という 3 つすべてのラッパー クラスを作成しましたPublication。私の以前のクラスは次のように継承されました:

BasePage : System.Web.UI.Page

Article : BasePage

BlogPost : BasePage

ColumnPost : BasePage

many other pages types : BasePage

私の新しいPublicationラッパーでは、次のようになります。

BasePage : System.Web.UI.Page

Publication : BasePage

Article : Publication

BlogPost : Publication

ColumnPost : Publication

今、私はこのようなことができます:

var dataSource = new List<Publication>();

articlesForThisControl().ForEach(a => dataSource.Add(a));
blogPostsForThisControl().ForEach(bp => dataSource.Add(bp));
columnPostsForThisControl().ForEach(cp => dataSource.Add(cp));

... dataSource.SortByDate() ...

さらに、C# のメディエーター パターンを使用して、重複するデータを必要とする可能性のある多くの競合するコントロールを仲介しています。以前は を持ってArticleMediatorいましたが、代わりに に変更しましたPublicationMediator

私の質問:

基本クラスのリストから派生クラスのリストを取得する最良/最も簡単な方法は何ですか? したがって、私のメディエーターは基本的に a を受け取り、 aList<Publication>を返しますList<Publication>。リスト内のすべてが であることがわかっている場合、Articleそれを元に戻して としてキャストする簡単な方法は何List<Article>ですか? 現在、私は多くのコードのように見える次のことを行っていますが、これが私がすべき方法であれば、私は大丈夫です。もっと簡単な方法があるかどうか疑問に思っています:

List<Article> articles = new List<Article>();

PublicationMediator.CalculateResults();
PublicationMediator.GetResults(this.UniqueID).PublicationList.Where(p => p is Article).ToList().ForEach(p => articles.Add((Article)p));

PublicationListプロパティは、List<Publication>メディエータが現在のコントロールの使用を許可することを決定したことを返します。ただし、必要なのは だけであることはわかっているので、リスト内のList<Article>それぞれを調べて、それが であることを確認してから、それを実際の に追加する必要があります。これを行う簡単な方法はありますか?PublicationArticleList<Article>

メディエーターが a を返すように変更したくない理由はList<Article>、場所によっては両方が必要なためBlogPost、実際にはリピーターを aにColumnPostバインドする必要があり、現在のアイテムがまたはであるかどうかを確認できるからです。List<Publication>ItemDataBoundBlogPostColumnPost

アップデート

私は受け入れられた答えを取り、それを拡張機能にしました:

public static List<T> GetSublist<T>(this List<Publication> publications) where T : Publication {
  return publications.OfType<T>().ToList<T>();
}
4

3 に答える 3

4

あなたが言ったので、リスト内のすべてが記事であることがわかっている場合は、次を使用することをお勧めしEnumerable.Castます:

PublicationList.Cast<Article>().ToList();

これは、仮説が偽の場合に例外をスローします。これは、プログラムにバグがあることを示している可能性があるため、おそらく良いことです。

于 2010-12-12T01:51:46.553 に答える
3

Enumerable.OfType拡張メソッドを使用できます。

PublicationMediator.CalculateResults();

List<Article> articles = PublicationMediator.GetResults(this.UniqueID)
                                            .PublicationList
                                            .OfType<Article>()
                                            .ToList();
于 2010-12-12T01:25:24.227 に答える
0

簡単な答えは、少なくともあなたの例で示したように、それを行う直接的な方法はないということです。あなたが探しているのは、フレームワーク呼び出しの共分散と反分散の 2 つの機能に関連しています。これらの特性は、次のリンクで確認できるように、他の多くの言語にも見られます。

ただし、C# では、インターフェイスとデリゲート レベルでのみ共分散があります。これらの概念を理解するのに役立つ記事へのリンクを次に示します。

共分散と反分散の概念を説明する記事。

複数のプログラミング言語における共分散の定義。

共分散と反分散に関するもう 1 つの優れた記事です。

一部の人が共分散を恐れる問題。

これにより、次の選択肢があります。

  1. 手で変換するのが最も明白です。
  2. インターフェイスで共分散の機能を使用するようにロジックを変換します。
  3. 最後に、変換を簡単にする Automapper と呼ばれるよく知られたライブラリのようなものを使用します。

これらの解決策のどれも非常に自然ではないことはわかっていますが、Microsoft が次のバージョンの C# で Lists に共分散を導入するまでは、これが唯一の解決策です。

于 2010-12-12T02:04:52.357 に答える