-1
class Program
{
    public class Pokemon
    {
        public string Name;
        public int Weight;
    }


    public class myReverserClass : IComparer
    {

        // Calls CaseInsensitiveComparer.Compare with the parameters reversed.
        int IComparer.Compare(Object x, Object y)
        {
            return ((new CaseInsensitiveComparer()).Compare(x, y));
        }
    }


    static void Main(string[] args)
    {
        IComparer myComparer = new myReverserClass();

        Random r = new Random();

        string[] pokemons = new string[10];
        pokemons[0] = "Bulbasaur";
        pokemons[1] = "Charmander";
        pokemons[2] = "Squirtle";
        pokemons[3] = "Groulit";
        pokemons[4] = "Caterpie";
        pokemons[5] = "Weedle";
        pokemons[6] = "Kakuna";
        pokemons[7] = "Beedrill";
        pokemons[8] = "Pidgey";
        pokemons[9] = "Rattata";

        string[] sovpad = new string[10];
        Pokemon[] pokemon = new Pokemon[10];

        for (int i = 0; i < pokemons.Length; i++)
        {
            string sovpadtrue;
            sovpadtrue = pokemons[r.Next(0, pokemons.Length)];
            for(int p = 0; p<sovpad.Length;p++)
            {
                if(sovpadtrue == sovpad[p])
                {
                    sovpadtrue = pokemons[r.Next(0, pokemons.Length)];
                    p = -1;
                }
            }
            sovpad[i] = sovpadtrue;
            pokemon[i] = new Pokemon();
            pokemon[i].Name = sovpadtrue;
            pokemon[i].Weight = r.Next(10, 1000);
        }
        Array.Sort(pokemon,myComparer);

        Console.ReadLine();
    }
}

クラス myReverserClass を追加して、最初に名前で、次に重みでポケモンの配列をソートする方法は? エラー: 少なくとも 1 つのオブジェクトでインターフェイス IComparable を実装する必要があります。1次元配列のみのMsdnの例。そして、msdn から取得した myReverserClass 。

4

2 に答える 2

3

CaseInsensitiveComparer.Compareドキュメントにはこれが含まれます:

a と b が両方とも文字列の場合、このメソッドは CompareInfo.Compare を使用して、大文字と小文字を区別せずに文字列を比較します。それ以外の場合は、いずれかのオブジェクトの IComparable 実装を使用します。つまり、a が IComparable を実装している場合、このメソッドは a の結果を返します。CompareTo (b); それ以外の場合、b が IComparable を実装している場合は、b の否定結果を返します。CompareTo (a)。

および例外として:

ArgumentException: a も b も IComparable インターフェイスを実装していません。

Pokemonこの場合、2 つのオブジェクトを比較Pokemonしていて、実装していないIComparableため、例外が発生します。

一般的な比較を使用して、 を実装するクラスを作成する方がはるかに優れていますIComparer<Pokemon>。例えば:

public class PokemonReverseNameComparer : IComparer<Pokemon>
{
    public int Compare(Pokemon x, Pokemon y)
    {
        return StringComparer.OrdinalIgnoreCase.Compare(y.Name, x.Name);
    }
}

ここでは、実際に引数の順序を逆にしたことに注意してください-コメントでそうすると主張Compare(x, y)しましたが、実際には. (ただし、これはウェイトの部分ではありません。一度に 1 つの部分を理解することが重要です...)

個人的には、「名前で比較」部分から反転を分離して、かなり異なる方法でアプローチし、LINQ も使用しようとしますが、それは別の問題です。LINQ を使用すると、非常に簡単になります。たとえば、次のようになります。

var ordered = pokemon.OrderByDescending(p => p.Name)
                     .ThenBy(p => p.Weight);
于 2012-06-24T18:34:59.577 に答える
0

Jon Skeetの提案に加えて、これを行うこともできます。

Array.Sort(
    pokemon,
    (pokemon1, pokemon2) => {
        // NOTE: Reverse arguments if you want reverse order.
        int result = string.Compare(pokemon1.Name, pokemon2.Name, true);
        if (result != 0)
            return result;
        if (pokemon1.Weight < pokemon2.Weight)
            return -1;
        if (pokemon1.Weight > pokemon2.Weight)
            return 1;
        return 0;
    }
);

Array.Sort<T>(T[], Comparison<T>)これにより、(を受け入れるオーバーロードの代わりに)を使用して、(LINQとは異なり)配列がインプレースで並べ替えられますIComparer

于 2012-06-24T18:53:43.377 に答える