Как: Динамически определенные свойства в .NET - PullRequest
1 голос
/ 08 октября 2009

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

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

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

Я хочу иметь возможность заменить свойство 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))

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

Ответы [ 2 ]

3 голосов
/ 08 октября 2009

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

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.

2 голосов
/ 08 октября 2009

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

   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 #. извините я не vb парень. Но вы можете легко перенести это.

...