views:

101

answers:

2

I've created a couple of Comparer classes for FileInfo objects to allow sorting by Name and LastWriteTime properties, but ideally I'd like to combine them into once class, so that I can compare/sort by any property simply by passing through the chosen property name.

However, I don't know how to go about this. My comparer class current includes:

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

I want to be able to substitute the Name property with the property name stored in the _sortColumn variable.

I'm expecting the solution to be rather simple, but as yet, I haven't been able to figure it out!

Solution:

I'd already got as far as researching Reflection, and had stumbled across PropertyInfo. But Fredriks solution cut down my search and provided a bit of structure, and I've come up with this (VB.Net) solution which seems to work nicely:

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

In reality, I have only have two columns to deal with so I could be slightly more explicit and t hus more performant. But this is a learning vehicle as much as it is a real-world problem so I've pursued this more sophisticated solution.

+3  A: 

Here is an example of how to do:

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

To extend this to a comparer scenario, you would simply need two variables for holding the data, one for each object.

Note, this is slower than accessing the properties directly, so if you know when coding what properties that you will be using, you are likely to get more performant code using a switch statement instead.

Fredrik Mörk
Should be easier using lambdas
Arnis L.
@Fredrik - twice within 24hrs - thanks.
CJM
@Arnis - Care to offer a Lambda-based solution?
CJM
+2  A: 

Hi, you can use extension methods to achive this.

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

And you can call the method like this

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

yeah this is a c# code. sorry am not a vb guy. But you can easily port this.

Cheers

Ramesh Vel

Ramesh Vel