質問

最近、私は、様々なトラブルも発生しようとした場合に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)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top