3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援→開発戻り浦島太郎状態の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。

(.Net)long→object→intへのキャスト時の注意

DataTable.Compute("SUM(clm1)") を使って、DataTableの集計値を求めたいと思ってました。

(DataTableのclm1列は int 型です。DataTable.Computeについては、(.Net)DataTableで特定の列の値を集計する参照。)

で下記のようなコードにすると InvalidCastException 例外が発生し、"指定されたキャストは有効ではありません。"と怒られます。。(C#)

//tblはDataTableインスタンス

int i = tbl.Compute("SUM(clm1"),null);

デバッガのウォッチ式で覗いてみると、DataTable.Compute は object 型で返り、内部では long 型となっているようです。

で、ちょっと実験をしてみました。

object o = new object() ;

long l = 50000;

int i = 0;

 

i = (int)l;

Console.WriteLine("long→int:" + i.ToString());

 

o = l;

Console.WriteLine("long→object:" + o.ToString());

 

i = (int)o; // ← ここで例外発生

Console.WriteLine("long→object→int:" + i.ToString());

long から int へは暗黙的キャストされますが、内部的に long 型の値を object に入れると object から int へのキャストはダメなようです。

下記のように、一旦 object から long に、そして int にキャストするとちゃんと動くようになりました。

i = (int)(long)o;

Console.WriteLine("long→object→long→long→int:" + i.ToString());

まぁ、当たり前といえば当たり前かもしれませんが、ちょっとハマりましたね。

DataTable.Compute が long を返すのも驚きです。(集計列は int なのに。。)

また、最近まで知りませんでしたが、 C# にはキャストに as 演算子というものが使えるようです。(参照型でしか使えませんが。。。)

as 演算子については@IT:.NET TIPS as演算子とキャストの違いはがわかりやすいです。