2017-06-10 9 views
0

へのIList をキャストするとき、私は次のコードで、 IList<T>ためにSortメソッドを実装しようとしている:私は知られているタイプの要素のリストのための方法を呼んでいる InvalidCastExceptionがIListの

public static void Sort<T>(this IList<T> list, Comparison<T> comparison) 
{ 
    ArrayList.Adapter((IList)list).Sort(Comparer<T>.Create(comparison)); 
} 

ArrayList.Adapter((IList)list).Sort(Comparer<T>.Create(comparison));

Iは、上記のメソッドを呼び出すと、 InvalidCastExceptionこの行で発生

cardwraplayout.Children.Sort((x, y) => 
{ 
    Card card1 = Cards.FindCardByIconId(x.Id); 
    Card card2 = Cards.FindCardByIconId(x.Id); 
    int result = card1.Rarity.CompareTo(card2.Rarity); 
    if (result == 0) 
    { 
     result = card1.Name.CompareTo(card2.Name); 
    } 
    return result; 
}); 

:、この比較のfuctionを提供

System.InvalidCastException: Specified cast is not valid.

自分のソート機能を実装するためにIList<T>IListにキャストできないのはなぜですか?

更新1: Comparer<T>からComparer<object>に変更しようとしても、同じ例外がスローされます。

public static void Sort<T>(this IList<T> list, Comparison<object> comparison) 
{ 
    ArrayList.Adapter((IList)list).Sort(Comparer<object>.Create(comparison)); 
} 

Image img1; 
Image img2; 

cardwraplayout.Children.Sort((x,y) => 
{ 
    img1 = (Image)x; 
    img2 = (Image)y; 
    Card card1 = Cards.FindCardByIconId(img1.Id); 
    Card card2 = Cards.FindCardByIconId(img2.Id); 
    int result = card1.Rarity.CompareTo(card2.Rarity); 
    if (result == 0) 
    { 
     result = card1.Name.CompareTo(card2.Name); 
    } 
    return result; 
}); 

アップデート2: 私は私に次のエラーを与えるであろう、他のクラスからいくつかのフィールドにアクセスする必要があるためはComparerクラスを作成する動作しません。

An object reference is required for the nonstatic field, method, or property "Cards"

+1

「IList」から「IList 」AFAIKへの暗黙のキャストはありません。 2つのインターフェースは単に互換性がありません。 'list.ToArray()。Sort ...'を実行するだけです。 – apokryfos

+1

@apokryfosは私のIListを変更するか、新しいArrayを作成しますか?リストを消去して再投入するのは高すぎます。 –

+0

例外を掲示できますか? – stybl

答えて

2

Why can't I cast my IList<T> to IList in order to implement my own sort function?

それが依存受け取ったリストの具体的なタイプに基づいています。 IList<T>IListを実装していません。具体的なクラスは、IList<T>IListの実装、IList<T>の実装、IListの実装、またはいずれも実装することを選択できません。彼らが名前を共有しているだけなので、2つの間には本質的な関係はありません。例えば

  • List<T>Collection<T>の両方を実装します。
  • ArraySegment<T>IList<T>であり、IListではありません。
  • StringCollectionIListであり、IList<string>ではありません。あなたがコンパイラを言っているIListにキャストすることにより

は、「それは大丈夫です、私はあなたよりも多くを知って、私は私が持っているクラスが本当にIListを実装しています知っています。」しかし、この場合のクラスはIListを実装していませんでした。したがって、失敗。

IList<T>をソートするには、IList<T>で動作するものを作成してください。IListが動作するようにしないでください。たとえば、T[]にすべてをコピーし、Array.Sortと呼び出して、結果をコピーし直すことができます。 (それは実際にはArrayList.Adapter(...).Sort(...)がやっていたよりも効率的です)。あるいは、標準の検索アルゴリズムの1つを手作業で行うこともできます。

+0

これはうまくいきましたが、効率が悪いです(IList は変更されていますが、変更可能ですが、変更する必要がありますが、手動で配列の内容を追加し直す必要があります) –

+0

@NicodeOry修正できる場合は、読み取り専用ですか?私はあなたがそこで何を意味しているのか分かりません。 – hvd

+0

私はXamarin.Formsを使ってレイアウトの子を修正しています。どうやら、彼らのAPIは 'layout.Children = myArray'を行うことができないように設計されていますが、あなたは' layout.Children.Add(item) 'を行うことができます。 –

関連する問題