19

次のシグネチャを持つIListSourceメソッドを必要とする実装を行っています。GetList()

IList GetList()

私は .NET Framework 2 を使用しており、次のように IList を実装するオブジェクトを返したいと考えています。

public System.Collections.IList GetList()
{
    return this._mydata; // Implements IList<MyDataRow>            
}

しかし、次のようなコンパイル エラーが発生しますCannot implicitly convert type MyData to System.Collections.IList

type の新しいリストを作成しList<MyDataRow>、入力してこのリスト オブジェクトを返すと、機能します。言い換えれば、これは機能します:

public System.Collections.IList GetList()
{
   List<MyDataRow> list = new List<MyDataRow>();
   foreach (MyDataRow row in this._mydata)
   {
       list.Add(row);
   }
   return list;
}

IList<T>しかし、 typeからに取得するためだけにリストを再作成する必要があるのは非常に非効率的IListです。を返せるのに を返せList<MyDataRow>' from 'GetList()ないのはなぜIList<MyDataRow>ですか? IList<MyDataRow>新しいリストを再作成せずに返す方法を知っている人はいますか?

アップデート:

_mydataメンバー変数は次のように宣言されます。

private MyData _mydata;

そしてMyData宣言されています:

public class MyData : IList<MyDataRow>
{
   ....
}
4

5 に答える 5

15

List<MyDataRow>fromを返すことができるのに、を返せGetList()ないのはなぜですか。IList<MyDataRow>

これは、List<T>implementsが 2 つの別個のインターフェースであることIListIList<T>キャストできないためです。IListあなたの質問に答えるには:

IList<MyDataRow>新しいリストを再作成せずに返す方法を知っている人はいますか?

具体的な型が実装されている場合IList(実装している場合List<T>)、明示的にキャストできます。

return (IList)this.mydata;

アップデート

更新に基づいて、実装するために更新MyDataするIList必要があります。それ以外の場合は、それを実装する新しいコレクションを返すしかありません。

または、MyDataが実際に一般的なリストである場合はList<T>、 から継承することをお勧めします。そうすれば、すぐに使用できる柔軟性と互換性が大幅に向上します。

class MyData : List<MyDataRow>
{
}
于 2012-09-19T13:42:29.810 に答える
4

IList<T>IListジェネリックバージョンのすべての実装が非ジェネリックバージョンと同じコントラクトを提供することを期待するのは合理的ではないため、拡張されません。それが拡張された場合IList、誰かがから返された値を取得し、、、またはGetListを呼び出すことを合理的に期待する可能性があります。それが約束です。Add(DateTime.Now)Add(Thread.CurrentThread)IList

List<T>それがあなたのリストを作品にコピーする理由です-両方のList<T>インターフェースを実装し、その(明示的に実装された)メソッドが不適切なパラメータータイプで呼び出されたときにスローします。IList

あなたが戻ることで逃げることができるならばIEnumerable、代わりにそれをしてください。代わりに戻ることができる場合はIList<MyDataRow>、それを行います。非ジェネリックIListリターンが本当に必要な場合は、インターフェイスを実装し、非MyDataRow値を適切に処理します。

于 2012-09-19T13:54:17.193 に答える
4

MyDataクラスは、ジェネリック バージョンとともに を実装する必要がありIListますIList<T>

class MyData : IList<MyDataRow>, IList
{
}
于 2012-09-19T13:45:47.823 に答える
4

データ コレクション クラスに実装IListするか、ラップIList<T>して実装するアダプターを作成しIListます。

public sealed class NonGenericList<T> : IList
{
    private readonly IList<T> _wrappedList;

    public NonGenericList(IList<T> wrappedList)
    {
        if(wrappedList == null) throw new ArgumentNullException("wrappedList");

        _wrappedList = wrappedList;
    }

    public int Add(object value)
    {
        _wrappedList.Add((T)value);
        return _wrappedList.Count - 1;
    }

    public void Clear()
    {
        _wrappedList.Clear();
    }

    public bool Contains(object value)
    {
        return _wrappedList.Contains((T)value);
    }

    public int IndexOf(object value)
    {
        return _wrappedList.IndexOf((T)value);
    }

    public void Insert(int index, object value)
    {
        _wrappedList.Insert(index, (T)value);
    }

    public bool IsFixedSize
    {
        get { return false; }
    }

    public bool IsReadOnly
    {
        get { return _wrappedList.IsReadOnly; }
    }

    public void Remove(object value)
    {
        _wrappedList.Remove((T)value);
    }

    public void RemoveAt(int index)
    {
        _wrappedList.RemoveAt(index);
    }

    public object this[int index]
    {
        get { return _wrappedList[index]; }
        set { _wrappedList[index] = (T)value; }
    }

    public void CopyTo(Array array, int index)
    {
        _wrappedList.CopyTo((T[])array, index);
    }

    public int Count
    {
        get { return _wrappedList.Count; }
    }

    public bool IsSynchronized
    {
        get { return false; }
    }

    public object SyncRoot
    {
        get { return this; }
    }

    public IEnumerator GetEnumerator()
    {
        return _wrappedList.GetEnumerator();
    }
}

使用法:

public System.Collections.IList GetList()
{
    return new NonGenericList<MyDataRow>(this._mydata);
}
于 2012-09-19T14:00:34.833 に答える
2

IList<T>を に直接変換できる場合はIList、(たとえば)Tそのメソッドを介して非オブジェクトで「汚染」される可能性のあるリストを返すことができますAdd(object)

于 2012-09-19T13:50:10.537 に答える