Вопрос

В настоящее время я работаю над приложением, где мне нужно загружать данные из базы данных SQL, а затем назначить полученные значения в свойства объекта. Я делаю это, используя разрабатывание, так как имена свойств и имена столбцов одинаковы. Однако многие из свойств используют пользовательский тип структуры, который в основном является валютной оберткой для десятичного типа. Я определил неявное преобразование в мою структуру:

public static implicit operator Currency(decimal d)
{
     return new Currency(d);
}

Это работает нормально, когда я использую его в коде. Однако, когда у меня есть это:

foreach (PropertyInfo p in props)
{
     p.SetValue(this, table.Rows[0][p.Name], null);
}

Он бросает ArgumentException, который не может преобразовать из системы. Я запутался, поскольку он отлично работает в любых других обстоятельствах.

Это было полезно?

Решение

я думать вам нужно сначала небровать значение в table.Rows[0][p.Name] как decimal.

Другими словами:

foreach (PropertyInfo p in props)
{
     if (p.PropertyType == typeof(Currency))
     {
         Currency c = (decimal)table.Rows[0][p.Name];
         p.SetValue(this, c, null);
     }
     else
     {
         p.SetValue(this, table.Rows[0][p.Name], null);
     }
}

Это проблема, которую я видел один или два раньше, поэтому я действительно решил Написать сообщение в блоге об этом. Отказ Кто-нибудь ищет немного больше объяснений, не стесняйтесь, чтобы дать ему чтение.

Другие советы

К сожалению, эти пользовательские операторы преобразования не используются временем выполнения; Они используются только компилятором во время компиляции. Так что если вы возьмете сильно набранные decimal и назначьте его на сильно набранный Currency, Компилятор вставит вызов на ваш оператор преобразования и счастливых. Однако, когда вы звоните SetValue Как вы делаете здесь, время выполнения ожидает, что вы придаете ему значение соответствующего типа; Время выполнения не имеет представления о том, что этот оператор преобразования существует, и никогда не будет называть это.

Я предполагаю что-то table имеет тип DataTable в вашем коде, поэтому первый индексатор возвращает DataRow, и второй возвращает object. Отказ потом PropertyInfo.SetValue также берет object как второй аргумент. В этом коде в этом коде есть в коде, Вот почему оператор перегруженного преобразования не применяется.

Вообще говоря, он применяется только тогда, когда известны статические типы (забывая о dynamic в C # 4.0 на данный момент). Он не применяется, когда бокс и распаковки вещей. В этом случае индексатор на DataRow коробки ценность, а PropertyInfo.SetValue пытается UNBOX его к другому типу - и не удается.

Пока я не отвечаю на вашу проблему, я думаю, что в такой ситуации будет более целесообразным использовать рамки ORM, подобную основу для объекта или Nibernate, которые будут сопоставлять ваши таблицы в ваши доменные объекты и обрабатывать все преобразования для вас. Использование чего-то вроде отражения, чтобы выяснить, какие поля для заполнения доменного объекта - медленный способ сделать это.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top