2012-09-19 12 views
17

へのIList から変換:私は、.NET Framework 2を使用していますが、私は、そのオブジェクトを返したいんだ 私は次のシグネチャを持つメソッド<code>GetList()</code>を必要<code>IListSource</code>実装しています非ジェネリックのIList

IList GetList() 

を次のようにするIListを実装しています

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

しかし、私は言ってコンパイルエラーを取得:Cannot implicitly convert type MyData to System.Collections.IListを。

のリストを作成してこのリストオブジェクトを返すと、それが動作します。

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

をしかし、ちょうどIListにタイプIList<T>からそれを得るためにリストを再作成するために持っていることは非常に非効率です。だから、他の言葉で、これは動作します。なぜ私はList<MyDataRow>' from 'GetList()を返しますが、IList<MyDataRow>は返せませんか?誰でも私に新しいリストを再投入せずにIList<MyDataRow>を返す方法を知っていますか?

はUPDATE:_mydataメンバ変数が宣言されている

private MyData _mydata; 

そしてMyDataが宣言されている:なぜ私はList<MyDataRow>GetList()から戻ることができ、それは

public class MyData : IList<MyDataRow> 
{ 
    .... 
} 
+0

は '_mydata'フィールドの宣言された型は何ですか? –

+1

@NicoleCalinoiu:彼が取得するエラーメッセージによると、それは 'MyData'です。 – Heinzi

答えて

14

あり、ただし、IList<MyDataRow>

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

IList<MyDataRow>を返す方法を知っている人はいませんか?

具体的なタイプは、(List<T>はない)、あなたが明示的に、例えば、それをキャストすることができIListを実装している場合

return (IList)this.mydata; 

更新

あなたの更新に基づいて、あなたがそうでなければ、がそれを実装しない新しいコレクションを返すしかないIListを実装するためにMyDataを更新する必要があります。また

MyDataは確かに一般的なリストであるならば、私は、あなたはそれがList<T>から継承する必要がありますが、例えば、箱から出して、より多くの柔軟性&互換性を得るその方法をお勧めします

class MyData : List<MyDataRow> 
{ 
} 
+0

これは問題を説明しますが、解決策を提供しません。myDataの型はIList ですが、彼は依然として.ToList()を呼び出す必要があり、避けたいと考えています。 –

+0

@Baboon 'myData'の型が' IList 'ですが、具体的な型が' List 'の場合、明示的なキャストがすべて必要です。 – James

+1

ありがとう、ジェームズ、あなたの詳細な答えです。リストから継承する提案は、リストのメンバーを自分のクラスにカプセル化するのではなく、実際に私の問題の最も簡単な解決策だったので、あなたに信用を与えるつもりです。助けてくれてありがとう。 – BruceHill

4

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

class MyData : IList<MyDataRow>, IList 
{ 
} 
+0

+1。私はクラス名を修正する自由を取った。 (OPのエラーメッセージによれば、クラス自体はMyDataRowではなくMyDataです)。 – Heinzi

+0

ありがとうございます、それも動作します:) – Xharze

2

それが直接IListIList<T>を変換することができなかった場合は、そのAdd(object)メソッドを介して(例えば)非Tオブジェクトと「汚染」することができ、リストを返すことができます。

+0

2番目の段落はその要点になりますが、最初の段落はわずかです。コンパイルエラーはIList がIListから派生したものであるため正確に発生します。 – shambulator

+0

優れたポイント。それに応じて修正し、訂正していただきありがとうございます。あなたは絶対に正しいです。 –

3

IList<T>は、ジェネリック版のすべての実装が非ジェネリック版と同じ契約を提供すると期待するのは妥当ではないため、IListは拡張されません。 IListを延長した場合、誰かがGetListから返された値を受け取り、合理的にコールすると期待します。 Add(DateTime.Now)またはAdd(Thread.CurrentThread)。それはIListが約束するものです。 List<T>作品にあなたのリストをコピーする理由です

からList<T>両方のインターフェイスを実装し、その(明示的に実装された)IList方法が不適切なパラメータの型と呼ばれていたときにスローされます。

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

+0

「IList」と「IList 」の実装の危険性を指摘するため+1 –

3

どちらかIList<T>をラップし、実装するアダプタを、あなたのデータ収集クラスにIListを実装したり、作成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); 
} 
関連する問題