2009-10-08 2 views
1

Я создал пару классов Comparer для объектов FileInfo, чтобы разрешить сортировку по свойствам Name и LastWriteTime, но в идеале я хотел бы объединить их в один класс, чтобы я может сравнивать/сортировать по любому свойству, просто пройдя через выбранное имя свойства.Практическое руководство. Динамически определенные свойства в .NET.

Однако я не знаю, как это сделать. Мой класс Comparer ток включает в себя:

Dim oX As FileInfo = CType(x, FileInfo) 
Dim oY As FileInfo = CType(y, FileInfo) 
Dim Result As Int16 = oX.Name.CompareTo(oY.Name) 

Я хочу, чтобы иметь возможность заменить свойство Имени с именем свойства, хранящимся в переменной _sortColumn.

Я ожидаю, что решение будет довольно простым, но пока я не смог понять это!

Решение:

я уже дошел до исследования Reflection, и он наткнулся на PropertyInfo. Но решение Fredriks сократить свой поиск и при условии, немного структуры, и я пришел к этому решению (VB.Net), который, кажется, работает хорошо:

 Dim oX_PI As PropertyInfo = CType(x, FileInfo).GetType.GetProperty(_sortColumn) 
    Dim oY_PI As PropertyInfo = CType(y, FileInfo).GetType.GetProperty(_sortColumn) 
    Dim Result As Int16 = oX_PI.GetValue(x, Nothing).CompareTo(oY_PI.GetValue(x, Nothing)) 

В действительности, у меня есть только две колонки чтобы иметь дело с этим, я мог бы быть немного более явным и более профессиональным. Но это учебное средство, так как это проблема реального мира, поэтому я преследовал это более сложное решение.

ответ

3

Вот пример того, как сделать:

Dim propertyName As String = "Extension" 
Dim fi As New FileInfo("C:\WINDOWS\explorer.exe") 
Dim pi As PropertyInfo =GetType(FileInfo).GetProperty(propertyName) 
Dim data As Object = pi.GetValue(fi, Nothing) ' data will be the string ".exe" ' 

Чтобы продлить это сценарий компаратора, вы бы просто нужно две переменных для проведения данных, по одному для каждого объекта.

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

+0

Должно быть проще использовать lambdas –

+0

@Fredrik - дважды в течение 24 часов - спасибо. – CJM

+0

@Arnis - Зачем предлагать решение на основе лямбда? – CJM

2

вы можете использовать методы расширения для достижения этого.

public static class ExtensionMethods 
{ 
    public static bool compare(this FileInfo F1,FileInfo F2,string propertyName) 
    { 
     try 
     { 
      System.Reflection.PropertyInfo p1 = F1.GetType().GetProperty(propertyName); 
      System.Reflection.PropertyInfo p2 = F2.GetType().GetProperty(propertyName); 

      if (p1.GetValue(F1, null) == p2.GetValue(F1, null)) 
      { 
       return true; 
      } 

     } 
     catch (Exception ex) 
     { 
      return false; 
     } 

     return false; 
    } 
} 

И вы можете вызвать метод как этот

System.IO.FileInfo fo = new System.IO.FileInfo("c:\\netlog.txt"); 
    System.IO.FileInfo f1 = new System.IO.FileInfo("c:\\regkey.txt"); 
    var isTrue = fo.compare(f1, "DirectoryName"); 

да это C# код. жаль, что я не парень. Но вы можете легко переносить это.

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