質問
私はこの質問は、前の質問で育ってきた何かに取り組むことは確かだろうが、私はそれを見つけることができませんでした。
パラメータとして、基本クラスの一般的なリストをとるC#クラスのメソッドがあります。私は、継承されたクラスのリストを渡す必要があり、これを行う方法を正確に知りません。私は私の試みでエラーを取得しています。
:以下は、このことを示すためのサンプルコードがありますpublic class A
{
public static void MethodC(List<A>)
{
// Do Something here with the list
}
}
public Class B : A
{
// B inherits from A, A is the Base Class
}
// Code utilizing the above method
List<B> listOfB = new List<B>();
A.MethodC( (List<A>) listOfB ); // Error: this does not work
A.MethodC( listOfB.ToList<typeof(A)>() ); // Error: this does not work
A.MethodC( listOfB.ConvertAll<A>(typeof(A)) ); // Error: this does not work
// how can I accomplish this? It should be possible I would think
注:ここに参照としての私の最終的な作業方法があります。私は私の問題へのよりよい解決策を得たが、私の質問がimpropertly言葉で表現されて以来、技術的には、質問への答えではなかったです。
public static DataTable
ObjectCollectionToDataTable<GLIST>
(List<GLIST> ObjectCollection) where GLIST
: BaseBusinessObject
{
DataTable ret = null;
if (ObjectCollection != null)
{
foreach ( var b in ObjectCollection)
{
DataTable dt = b.ToDataTable();
if (ret == null)
ret = dt.Clone();
if (dt.Rows.Count > 0)
ret.Rows.Add(dt.Rows[0].ItemArray);
}
}
return ret;
}
解決
あなたが利用できるLINQを持っている場合は、あなたが行うことができます。
var ListOfA = ListOfB.Cast<A>().ToList();
他のヒント
あなたはそれを行うことはできません。それが許可されていない理由を理解するには、それはAdd
にキャストした後List<Derived>
がList<Base>
で呼び出された場合に何が起こるか想像します。
また、C#4.0は異なるものになることを意味している答えは間違っています。リストには、これを実行できるように変更されることはありません。 IEnumerable
意志だけ - それはアイテムをコレクションに追加することはできませんので、
更新:あなたは、もはや同じリストを渡しているので、それはあなたが行ってきた溶液中で働く理由はありません。あなたは、元のコピーである全く新しいリストを作成しています。私はリストを修正について尋ねられたのはこのためです。 MethodC
は、リスト上のアイテムの数に変更を行った場合、これらの変更は、コピーではなく、元のリストに加えられたことになる。
私は次のようにあなたのための理想的なソリューションだと思います:
public abstract class A
{
public void MethodC<TItem>(List<TItem> list) where TItem : A
{
foreach (var item in list)
item.CanBeCalled();
}
public abstract void CanBeCalled();
}
public class B : A
{
public override void CanBeCalled()
{
Console.WriteLine("Calling into B");
}
}
class Program
{
static void Main(string[] args)
{
List<B> listOfB = new List<B>();
A a = new B();
a.MethodC(listOfB);
}
}
この溶液を用いて、あなたが直接List<B>
を渡すことができます最初にそれにその奇妙な変換を行うために必要とせずにMethodC
する方法、注意してください。だから、不要なコピーます。
これが機能する理由は、私たちの代わりに、それはMethodC
のリストでなければならないと主張の、A
から派生し何のリストを受け入れるようにA
を言ったからです。
あなたは現在のC#バージョンにおける共分散の欠如に対処しています。ここではそれを行うための一つの方法があります:
listOfB.Cast<A>();
ここで間違った型のリストに任意のオブジェクトを除外します答えはあります。これは私の意見でははるかに安全な方法です。
List<A> ListOfA = ListOfB.OfType<A>().ToList();
OfTypeメソッドは、キャストがエラーをスローしますと、間違った派生クラスの項目を除外します。