2009-01-26 5 views
2

У меня есть пользовательский объект (например, только код для простоты понимания) ...Доступ к свойствам объекта из строки представлений

public class MyClass 
{ 
    private string name; 
    private int increment; 
    private Guid id; 

    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    public int Increment 
    { 
     get { return increment; } 
     set { increment = value; } 
    } 

    public Guid Id 
    { 
     get { return id; } 
     set { id = value; } 
    } 
} 

... и пользовательской коллекции этого класса ...

public class MyClassCollection : Collection<MyClass> 
{ 

} 

Я искал, чтобы написать процедуры сортировки для коллекции, которая будет иметь следующий открытый метод ...

public void Sort(params string[] sortProperties) 
    { 
     if (sortProperties == null) 
     { 
      throw new ArgumentNullException("sortProperties", "Parameter must not be null"); 
     } 

     if ((sortProperties.Length > 0) && (Items.Count > 1)) 
     { 
      foreach (string s in sortProperties) 
      { 
     // call private sort method 
       Sort(s); 
      } 
     } 
    } 

... и частный метод сортировки будет принимать параметр имени свойства ...

private void Sort(string propertyName) 
    { 

    } 

То, что я хочу сделать, это быть в состоянии передать в наборе имен свойств в метод ...

 MyClassCollection current = new MyClassCollection(); 

     // setup a objects in the collection 
     current = GetCollectionData(); 

     // sort by Name, then by Increment 
     current.Sort("Name", "Increment"); 

Использование имен свойств, переданных в метод, я хочу, чтобы проверить, есть ли у него свойство этого имени, если он так работает, то какой тип он есть, а затем запускается через его вид.

Временный обходной путь, который я в настоящее время есть, это ...

private void Sort(string propertyName) 
    { 
     // convert to List 
     List<MyClass> myCurrentClass = Items as List<MyClass>; 

     // sort 
     if (myCurrentClass != null) 
     { 
      switch (propertyName) 
      { 
       case "Name": 
        myCurrentClass.Sort(delegate(MyClass myClassOne, MyClass myClassTwo) 
           { 
            return 
             Comparer<string>.Default.Compare(myClassOne.Name, 
                      myClassTwo.Name); 
           } 
         ); 
        break; 

       case "Increment": 
        myCurrentClass.Sort(delegate(MyClass myClassOne, MyClass myClassTwo) 
           { 
            return 
             Comparer<int>.Default.Compare(myClassOne.Increment, 
                     myClassTwo.Increment); 
           }); 
        break; 
      } 
     } 
    } 

... но в идеале я хотел бы перейти на основной тип собственности (строка, INT и т.д.) и с помощью различное количество вызовов делегатов для типов сортировки. Я огляделся, но я не нашел ничего, что указывает на меня в правильном направлении. Я взглянул на размышления, но я не мог видеть ничего, что могло бы мне помочь.

Возможно ли это? и если да, то как ?!

Cheers!

ответ

1

После того, как я ненадолго ударил головой о проблему и надеясь на поезд домой, я решил, что попытаюсь выбить ответ. Используя сочетание использования Джона указателей и Фредерика класса PropertyInfo и сохранить оригинальную идею включения базового типа объекта, это то, что я придумал ...

private void Sort_version2(string propertyName) 
    { 
     // convert to list 
     List<MyClass> myCurrentClass = Items as List<MyClass>; 

     string typeOfProperty; 
     PropertyInfo pi; 

     // sort 
     if ((myCurrentClass != null) && (MyClass.HasDetailAndExtract(propertyName, out typeOfProperty, out pi))) 
     { 
      switch(typeOfProperty) 
      { 
       case "System.String": 
        myCurrentClass.Sort(delegate(MyClass one, MyClass two) 
              { 
               return 
                Comparer<string>.Default.Compare(pi.GetValue(one, null).ToString(), 
                        pi.GetValue(two, null).ToString()); 
              }); 
        break; 

       case "System.Int32": 
        myCurrentClass.Sort(delegate (MyClass one, MyClass two) 
              { 
               return 
                Comparer<int>.Default.Compare(
                 Convert.ToInt32(pi.GetValue(one, null)), 
                 Convert.ToInt32(pi.GetValue(two, null))); 
              }); 
        break; 
       default: 
        throw new NotImplementedException("Type of property not implemented yet"); 
      } 
     } 
    } 

Я документально мыслительный процесс и более подробную информацию о my blog дайте мне знать, что вы думаете!

Благодаря Джону и Фредерика за помощь :-)

3

Отражение - это путь - посмотрите на Type.GetProperty(string name). Создание правильного компаратора может быть сложным после этого - вы можете написать общий метод, а затем вызвать это с отражением на основе типа свойства. Боюсь, все это становится довольно неприятно, но это определенно возможно.

+0

Вы не могли использовать обычные, не родовое Comparer, который принимает объекты в качестве аргументов? –

+0

Возможно. не могу сказать, что я когда-либо использовал не-общую форму - даже не знал о ее существовании! –

+0

+1 Спасибо за ваши указатели. Твой вместе с Фредериком удалось получить меня через :-) – WestDiscGolf

3
private void Sort(string propertyName) 
{ 
    List<MyClass> myCurClass = ... 

    myCurClass.Sort(delegate(MyClass left, MyClass right){ 

     PropertyInfo lp = typeof(MyClass).GetProperty (propertyName); 

     Comparer.Default.Compare (pi.GetValue(left), pi.GetValue(right)); 


    }); 
} 

Я думаю, вам стоит начать. :) (Не проверено, не скомпилировано, но вы поймете эту идею)

+0

+1 Спасибо за ваши указатели!Позвольте мне знать, что вы думаете о решении, которое я придумал. – WestDiscGolf

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