В настоящее время я работаю над модулем динамической загрузки. Идея состоит в том, чтобы определять только файл и контракт данных для каждого нового файла. В настоящее время я использую отражение с 2 foreach, это тяжелый код для этого. Как вы можете видеть в коде, у меня есть объект, содержащий файл csv и 2 других списка. Эти два списка содержат все свойства объекта, для которого я хотел бы выполнить проверку данных.

var myCustomObjects = CsvSettings(new CsvReader(readFile, config)).GetRecords<MyCustomObject>();
var decimalProprties = GetPropertyNames<MyCustomObject>(typeof(decimal)).ToList();
var dateProprties = GetPropertyNames<MyCustomObject>(typeof(DateTime)).ToList();

foreach (var myCustomObject in myCustomObjects)
{
     foreach (var dateProperty in dateProprties)
     {
        var value = myCustomObject.GetType().GetProperty(dateProperty).GetValue(myCustomObject, null);
        Console.WriteLine(value); //code to check and report the value
     }
     Console.WriteLine(myCustomObject.Een + "|" + myCustomObject.Twee + "|" + myCustomObject.Drie);
}

Как я могу сделать это с помощью выражения или даже другого способа сделать менее тяжелый код?

0
Freddy 31 Мар 2014 в 11:31
Что вы имеете в виду под «тяжелым» кодом? В конце концов, это отражение ...
 – 
RePierre
31 Мар 2014 в 11:53
1
Что вас больше всего беспокоит? Представление? Читаемость? Простота? ...?
 – 
Marc Gravell
31 Мар 2014 в 12:04
Производительность. Если мой csv имеет 9 тыс. Строк и я проверяю 10 свойств, он будет запускать отражение 90 тыс. Раз. Я бы предпочел, чтобы отражение загружалось 10 раз и загружало его в память ...
 – 
Freddy
31 Мар 2014 в 12:44

1 ответ

Лучший ответ

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

public static IEnumerable<KeyValuePair<string, T>> PropertiesOfType<T>(object myObject)
{
    var properties = 
        from   property in myObject.GetType().GetProperties()
        where  property.PropertyType == typeof(T) && property.CanRead
        select new KeyValuePair<string, T>(property.Name, (T)property.GetValue(myObject));

    return properties;
}

Тогда вы можете избежать дополнительного вызова GetProperty() во внутреннем цикле:

foreach (var myCustomObject in myCustomObjects)
{
    foreach (var dateProperty in PropertiesOfType<DateTime>(myCustomObject))
    {
        Console.WriteLine(dateProperty.Value);  // code to check and report the value.
    }
}

Также обратите внимание, что, похоже, вам не нужны вызовы .ToList().

1
Matthew Watson 31 Мар 2014 в 11:56
Проблема, с которой я столкнулся с этим решением, заключается в том, что отражение вызывается так много раз. Думаю, из-за этого потребуется больше усилий и времени для запуска кода.
 – 
Freddy
31 Мар 2014 в 17:19
1
Вы рассчитали время, чтобы определить, проблема ли это? Отражение в C # на самом деле происходит довольно быстро.
 – 
Matthew Watson
31 Мар 2014 в 18:45