Frage

Im Moment arbeite ich an einer Anwendung, wo ich Daten aus einer SQL-Datenbank zu laden und dann die abgerufenen Werte in die Eigenschaften eines Objekts zuweisen. Ich tue dies durch Reflexion verwendet wird, da die Eigenschaftsnamen und Spaltennamen identisch sind. viele der Eigenschaften werden mit einem benutzerdefinierten Strukturtyp jedoch, die im Grunde eine Währung Wrapper für den Dezimal-Typen ist. Ich habe eine implizite Konvertierung in meiner Struktur definiert:

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

Das funktioniert gut, wenn ich es im Code verwenden. Allerdings, wenn ich diese:

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

Es wirft ein Argument besagt, dass es nicht von System.Decimal bis Währung umwandeln kann. Ich bin verwirrt, da es in Ordnung in anderen Umständen funktioniert.

War es hilfreich?

Lösung

I denken müssen Sie zuerst unbox den Wert in table.Rows[0][p.Name] als decimal.

Mit anderen Worten:

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

Dies ist ein Problem, das ich gesehen habe, einmal oder zweimal vor, so dass ich eigentlich beschlossen, einen Blogeintrag darüber schreiben . Jeder für ein wenig mehr Erklärung suchen, können Sie ihm eine Lese geben.

Andere Tipps

Leider ist diese benutzerdefinierten Konvertierungs Betreiber nicht von der Laufzeit verwendet; sie werden nur durch den Compiler bei der Kompilierung verwendet. Also, wenn Sie nehmen eine stark typisierte decimal und Zuweisen zu einem stark typisierte Currency, wird der Compiler einen Aufruf der Conversion-Operator und jeder ist glücklich ein. Wenn Sie jedoch SetValue nennen, wie Sie hier machen, die Laufzeit erwartet Sie ihm einen Wert des entsprechenden Typs geben; die Laufzeit keine Ahnung hat, dass diese Umwandlung Betreiber vorhanden ist, und es wird nicht immer nennen.

Ich gehe davon aus, dass table vom Typ DataTable im Code ist, so dass der erste Indexer eine DataRow zurückkehrt, und die zweite kehrt ein object. Dann PropertyInfo.SetValue nimmt auch eine object als zweites Argument. An keiner Stelle in diesem Code ein gegossenes geschieht im Code , weshalb die überladene Konvertierungsoperator nicht angewendet wird.

Im Allgemeinen ist es nur angewandt, wenn statische Typen bekannt sind (zu vergessen dynamic in C # 4.0 für den Moment). Es ist nicht, wenn Boxen und Unboxing Dinge angewendet. In diesem Fall wird der Wert der Indexer auf DataRow Boxen und PropertyInfo.SetValue versucht es auf eine andere Art unbox -. Und nicht

Während ich bin nicht Ihr Problem zu beantworten, ich glaube, in einer solchen Situation wäre es sinnvoller sein, ein ORM-Framework wie das Entity Framework oder NHibernate zu verwenden, die Ihre Tabellen in Ihre Domain-Objekte abbildet und behandeln alle die Konvertierungen für Sie . Mit so etwas wie Reflexion, um herauszufinden, was in einem Domain-Objekt zu füllen Felder ist ein langsamer Weg, es zu tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top