an excellent capability of C# language and compiler
2015-11-13 08:34
441 查看
Sometimes you want to write code that works for different primitive types, and as C# doesn't support generic type constraints on primitive type hence you can't avoid writing more code, but you may still one way or another minimise the code you have to write and mysteriously end up having to write something like below,
The main concern is on line 7, where a seemingly boxing and unboxing is happening on primitive type dval (which is of double type here) and this is done like this
And we know that T is determined at compile time and is also double, so we hope that the compiler is smart enough to eliminate the unnecessary boxing and interpret that line as below at run time.
It looks like a simple task as everything can be easily evaluated at compile time. But we need proof before we can be sure.
The most reliable way is to examine the IL, however the following code is sufficient.
If we compare them, the generic method takes same amount of time as the non-generic counterpart for any iterations. To this point, I'm quite convinced.
And one more thing which is a bit disappointing kind of adds to the confidence: we can't do such thing like below, which will cause a run time exception InvalidCastException: Specifid cast is not valid
Not even this,
public override bool GetValue<T>(int row, int col, out T val) { CacheBlockDouble cache; int r, c; GetCacheAndPoint(row, col, out cache, out r, out c); var dval = cache.Data[r, c]; val = (T) (object) dval; return dval != NoDataValue; }
The main concern is on line 7, where a seemingly boxing and unboxing is happening on primitive type dval (which is of double type here) and this is done like this
And we know that T is determined at compile time and is also double, so we hope that the compiler is smart enough to eliminate the unnecessary boxing and interpret that line as below at run time.
val = dval;
It looks like a simple task as everything can be easily evaluated at compile time. But we need proof before we can be sure.
The most reliable way is to examine the IL, however the following code is sufficient.
using System; namespace boxing { class Program { public static T BoxingTest<T>(double v) { T result = (T)(object)v; return result; } public static double NonboxingTest(double v) { return v; } static void Main(string[] args) { long countDown = 900000000; const int buffersize = 4096; var buffer = new double[buffersize]; var t1 = DateTime.UtcNow; var i = 0; for (; countDown>0; countDown--) { var t = BoxingTest<double>(i); //var t = NonboxingTest(countDown); buffer[i] = t; i++; if (i == 4096) { i = 0; } } var t2 = DateTime.UtcNow; Console.WriteLine("finished in {0} secs", (t2-t1).TotalSeconds); } } }
If we compare them, the generic method takes same amount of time as the non-generic counterpart for any iterations. To this point, I'm quite convinced.
And one more thing which is a bit disappointing kind of adds to the confidence: we can't do such thing like below, which will cause a run time exception InvalidCastException: Specifid cast is not valid
var d = 1.0; var f = (float)(object)d;
Not even this,
var f = 1.0f; var d = (double)(object)f;
相关文章推荐
- c# 函数相关练习
- C#学习笔记 特性
- WPF中用后台C#代码为TabItem设置Background属性
- (C#) 求两个数组的交集
- string[][]和string[,]的区别
- C#WebBrowser控件使用教程与技巧收集
- C# 多线程学习系列三:线程优先级、线程同步以及向线程传递参数
- C#进入Dll文件后仍提示找不到文件
- 【C#】字符串与字符数组
- C#播放音乐,调用程序
- 【C#】Observer设计模式委托事件的使用(获取Subject多个属性)
- C#更改系统时间
- 使用csc.exe构建C#应用程序
- C# DLL文件注册问题(涉及AxInterop.WMPLib.dll等)
- Leetcode-149-Max Ponits on a Line C#
- c# 操作excle
- c# 利用Log Parser制作简易可视化netmon抓包分析工具
- C#实现Dll(OCX)控件自动注册的两种方法(转)
- .NET根据wsdl文件解析成调用的类文件,客户端方法
- C#学习笔记 字符串和正则表达式