C#に変換できないからIEnumerable<Base> にIEnumerable<Derived>
-
10-07-2019 - |
質問
最近、私は、様々なトラブルも発生しようとした場合にAddRange(IEnumerable)をリストアップしました。くクラシックの問題がないんですが。
この方法を見込んで一覧パラメータのように眩しくなりすぎないので、一覧いう追加の拠点の一覧ですが不可能である。
だいこくてIEnumerables自身での変更はできませんとすべき作品です。
このコードと思ったのは以下のようなものです:
class Foo
{
}
class Bar : Foo
{
}
class FooCol
{
private List<Foo> m_Foos = new List<Foo> ();
public void AddRange1(IEnumerable<Foo> foos)
{
m_Foos.AddRange (foos); // does work
}
public void AddRange2<T>(IEnumerable<T> foos) where T : Foo
{
m_Foos.AddRange (foos); // does not work
}
}
class Program
{
static void Main(string[] args)
{
FooCol fooCol = new FooCol ();
List<Foo> foos = new List<Foo> ();
List<Bar> bars = new List<Bar> ();
fooCol.AddRange1 (foos); // does work
fooCol.AddRange1 (bars); // does not work
fooCol.AddRange2 (foos); // does work
fooCol.AddRange2 (bars); // does work
}
}
またパスポートのコンパイラのAddRange2方法が、この移転の問題です。
私の考え方を具?この限定の言語でデザイン?
IIRC、このような業務を追加したJava1.5ういC#のいくつかの点で、今後も来てるのか-----。
解決
ここでは共分散し、固定クライアントまで、フルのC#4.0/.純4.0の製品をご用意しています。ましたが、今後とも、一般のオプションは最善の答え( IEnumerable<T>
- ない IList<T>
など).
が一般的方法までを考えるので T
.このまま使用 Cast<T>
または OfType<T>
とLINQに何かを達成することになる。
他のヒント
C#3.0では、「キャスト」を使用できます。拡張メソッド。 System.Linqをインポートしてから次のコードを使用する場合:
public void AddRange2<T>(IEnumerable<T> foos) where T : Foo
{
m_Foos.AddRange (foos.Cast<Foo>());
}
それはあなたのために働くはずです。
拡張メソッドには回避策があります:
public static IEnumerable<TBase> ToBaseEnumerable<TBase, TDerived>( this IEnumerable<TDerived> items ) where TDerived : TBase {
foreach( var item in items ) {
yield return item;
}
}
...
IEnumerable<Employee> employees = GetEmployees(); //Emplyoee derives from Person
DoSomethingWithPersons( employees.ToBaseEnumerable<Person, Employee>() );
ただし、&quot;&lt; Person、Employee&gt;&quot;少し厄介です:/。
もちろん、キャストソリューションはクラスキャスト例外を生成する可能性があります。 列挙可能な拡張機能の回避策を投稿した人は、それが厄介だと言った。 私は半分だけ厄介な解決策を思いついた、それを使用するかどうかわからない:
public static class UpTo<T>
{
public static IEnumerable<T> From<F>(IEnumerable<F> source) where F:T
{
// this cast is guaranteed to work
return source.Select(f => (T) f);
}
}
使用法:
IEnumerable哺乳類= UpTo&lt; Mammal&gt; .From(kennel.Dogs)