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演算子とキャストの違いはがわかりやすいです。