5

現在、SQLデータベースからデータをロードしてから、取得した値をオブジェクトのプロパティに割り当てる必要があるアプリケーションに取り組んでいます。プロパティ名と列名が同じであるため、リフレクションを使用してこれを行っています。ただし、プロパティの多くは、基本的に10進型の通貨ラッパーであるカスタム構造体型を使用しています。構造に暗黙の変換を定義しました。

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

System.DecimalからCurrencyに変換できないことを示すArgumentExceptionをスローします。それは他の状況でうまく機能するので、私は混乱しています。

4

4 に答える 4

10

残念ながら、これらのユーザー定義の変換演算子はランタイムでは使用されません。これらは、コンパイル時にコンパイラーによってのみ使用されます。したがって、強く型付けdecimalされたものを強く型付けされたものに割り当てるとCurrency、コンパイラーは変換演算子への呼び出しを挿入し、誰もが満足します。ただし、SetValueここで行っているように呼び出すと、ランタイムは適切なタイプの値を指定することを期待します。ランタイムは、この変換演算子が存在することを認識しておらず、呼び出すこともありません。

于 2010-05-05T19:26:56.263 に答える
3

最初に値をとして箱から出す必要があると思います。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);
     }
}

これは私が以前に一度か二度見た問題なので、私は実際にそれについてのブログ投稿を書くことにしました。もう少し説明をお探しの方は、お気軽に読んでください。

于 2010-05-05T19:27:40.630 に答える
2

これはコード内tableのタイプであると想定しているため、最初のインデクサーはを返し、2番目のインデクサーはを返します。次に、2番目の引数としても取ります。このコードのどこにもキャストは発生ません。そのため、オーバーロードされた変換演算子は適用されません。DataTableDataRowobjectPropertyInfo.SetValueobject

dynamic一般的に言えば、静的型がわかっている場合にのみ適用されます( C#4.0では今のところ忘れています)。物を箱詰めしたり箱から出したりするときは適用されません。この場合、インデクサーDataRowは値をボックスPropertyInfo.SetValue化し、別のタイプにボックス化を解除しようとしますが、失敗します。

于 2010-05-05T19:26:07.407 に答える
0

私はあなたの問題に答えていませんが、この種の状況では、テーブルをドメインオブジェクトにマップし、すべての変換を処理するEntityFrameworkやNHibernateなどのORMフレームワークを使用する方が適切だと思います。リフレクションのようなものを使用して、ドメインオブジェクトに入力するフィールドを把握するのは、時間がかかる方法です。

于 2010-05-05T19:25:32.503 に答える