2012-06-24 2 views
-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, чтобы отсортировать массив покемона, сначала по имени, а затем вес? Ошибка: по крайней мере один объект должен реализовать интерфейс IComparable. На примере Msdn только одномерного массива. И myReverserClass из msdn.По крайней мере, один объект должен реализовать интерфейс IComparable

ответ

2

CaseInsensitiveComparer.Compare документация включает в себя следующее:

If a and b are both strings, this method uses CompareInfo.Compare to compare the strings with the casing ignored; otherwise, it uses the IComparable implementation of either object. That is, if a implements IComparable, then this method returns the result of a. CompareTo (b); otherwise, if b implements IComparable, then it returns the negated result of b. CompareTo (a).

и исключения:

ArgumentException: Neither a nor b implements the IComparable interface.

В этом случае, вы сравниваете два Pokemon объектов и 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). (Это не делает весовую часть - важно, чтобы вы понимали одну часть за раз ...)

Лично я бы подошел к чему-то совсем по-другому, отделив разворот от части «сравнить по имени» , и я также попытаюсь использовать LINQ, но это другой вопрос. LINQ делает действительно легко - например:

var ordered = pokemon.OrderByDescending(p => p.Name) 
        .ThenBy(p => p.Weight); 
0

В дополнение к предложениям Джон Скит, вы также можете сделать это:

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; 
    } 
); 

Это сортирует массив на месте (в отличие от LINQ), используя Array.Sort<T>(T[], Comparison<T>) (вместо перегрузки, которая принимает IComparer).

Смежные вопросы