2009-10-08 1 views
1

J'ai créé deux classes de comparaison pour les objets FileInfo afin de permettre le tri par propriétés Name et LastWriteTime, mais idéalement, je voudrais les combiner en une seule classe, de sorte que je peut comparer/trier par n'importe quelle propriété simplement en passant par le nom de propriété choisi.Comment: propriétés définies dynamiquement dans .NET

Cependant, je ne sais pas comment procéder. Mon actuelle classe comprend comparateur:

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

Je veux être en mesure de remplacer la propriété Name avec le nom de la propriété stockée dans la variable _sortColumn.

Je m'attends à ce que la solution soit plutôt simple, mais je n'ai pas encore réussi à la comprendre!

Solution:

je avais déjà eu aussi loin que la recherche de réflexion, et avait trébuché à travers PropertyInfo. Mais la solution Fredriks coupé ma recherche et a fourni un peu de la structure, et je suis venu avec cette solution (VB.Net) qui semble fonctionner très bien:

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

En réalité, je n'avoir plus que deux colonnes pour faire face à ce que je pourrais être un peu plus explicite et t hus plus performant. Mais c'est un véhicule d'apprentissage autant que c'est un problème du monde réel, j'ai donc poursuivi cette solution plus sophistiquée.

Répondre

3

Voici un exemple de la façon de le faire:

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" ' 

Pour étendre à un scénario de comparateur, vous avez simplement besoin de deux variables pour maintenir les données, un pour chaque objet. Notez que c'est plus lent que d'accéder directement aux propriétés, donc si vous savez coder les propriétés que vous utiliserez, vous obtiendrez probablement un code plus performant en utilisant une instruction switch.

+0

Devrait être plus facile en utilisant lambdas –

+0

@Fredrik - deux fois en 24 heures - merci. – CJM

+0

@Arnis - Vous souhaitez proposer une solution Lambda? – CJM

2

Vous pouvez utiliser des méthodes d'extension pour réaliser ceci.

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

Et vous pouvez appeler la méthode comme celui-ci

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

ouais c'est un code C#. désolé je ne suis pas un gars vb. Mais vous pouvez facilement le porter.