从代码写的角度上说,有一定的方便性,但还需要从性能的角度做为主要参考因素
下面贴下性能相磁的测评:
class Test :ITest{ public int Calculate(int i)=>i++; //static public Test Create()=>new Test(); } interface ITest { int Calculate(int i); } [TestMethod] public void m22() { var dy_checker = new Stopwatch(); var obj_checker = new Stopwatch(); var time = 100 * 100000; var x2 = typeof(Test); ITest w = (ITest)Activator.CreateInstance(x2); obj_checker.Start(); for (int i = 0; i < time; i++) { //x2.GetMethod("Calculate").Invoke(w, new object[] { 1 }); w.Calculate(1); } obj_checker.Stop(); dy_checker.Start(); for (int i = 0; i < time; i++) { dynamic x3 = w; x3.Calculate(1); } dy_checker.Stop(); Console.WriteLine("dy:{0}", dy_checker.ElapsedMilliseconds); Console.WriteLine("obj:{0}", obj_checker.ElapsedMilliseconds); } [TestMethod] public void m21() { var dy_checker = new Stopwatch(); var obj_checker = new Stopwatch(); var time = 100 * 100000; var x2 = typeof(Test); Test w = (Test)Activator.CreateInstance(x2); obj_checker.Start(); for (int i = 0; i < time; i++) { x2.GetMethod("Calculate").Invoke(w,new object[]{1 }); } obj_checker.Stop(); dy_checker.Start(); for (int i = 0; i < time; i++) { dynamic x3 = w; x3.Calculate(1); } dy_checker.Stop(); Console.WriteLine("dy:{0}", dy_checker.ElapsedMilliseconds); Console.WriteLine("obj:{0}", obj_checker.ElapsedMilliseconds); } [TestMethod] public void m20() { var dy_checker = new Stopwatch(); var obj_checker = new Stopwatch(); var time = 100 * 100000; obj_checker.Start(); for (int i = 0; i < time; i++) { object x2 = new Test(); ((Test)x2).Calculate(1); } obj_checker.Stop(); dy_checker.Start(); for (int i = 0; i < time; i++) { dynamic x3 = new Test(); x3.Calculate(1); } dy_checker.Stop(); Console.WriteLine("dy:{0}", dy_checker.ElapsedMilliseconds); Console.WriteLine("obj:{0}", obj_checker.ElapsedMilliseconds); } [TestMethod] public void m19() { var dy_checker = new Stopwatch(); var obj_checker = new Stopwatch(); var var_checker = new Stopwatch(); var time = 100 * 100000; var_checker.Start(); for (int i = 0; i < time; i++) { var x3 = 3; var x33 = x3 + 5; } var_checker.Stop(); obj_checker.Start(); for (int i = 0; i < time; i++) { object x2 = 3; var x22 = (int)x2 + 5; } obj_checker.Stop(); dy_checker.Start(); for (int i = 0; i < time; i++) { dynamic x1 = 3; var x11 = x1 + 5; } dy_checker.Stop(); Console.WriteLine("dy:{0}", dy_checker.ElapsedMilliseconds); Console.WriteLine("obj:{0}", obj_checker.ElapsedMilliseconds); Console.WriteLine("var:{0}", var_checker.ElapsedMilliseconds); } [TestMethod] public void m18() { var dy_checker = new Stopwatch(); var obj_checker = new Stopwatch(); var time=100*100000; obj_checker.Start(); for (int i = 0; i < time; i++) { object x2 = 3; var x22 = (int)x2 + 5; } obj_checker.Stop(); dy_checker.Start(); for (int i = 0; i < time; i++) { dynamic x1 = 3; var x11 = x1 + 5; } dy_checker.Stop(); Console.WriteLine("dy:{0}",dy_checker.ElapsedMilliseconds); Console.WriteLine("obj:{0}",obj_checker.ElapsedMilliseconds); }
测试名称: m18
测试结果: 已通过
结果 StandardOutput:
dy:211
obj:85
测试名称: m19
测试结果: 已通过
结果 StandardOutput:
dy:221
obj:90
var:22
测试名称: m20
测试结果: 已通过
结果 StandardOutput:
dy:302
obj:131
测试名称: m21
测试结果: 已通过
结果 StandardOutput:
dy:224
obj:3057
测试名称: m22
测试结果: 已通过
结果 StandardOutput:
dy:229
obj:43
///
结论从性能上考虑, dynamic没有object好,单从装折箱的测试来看,是3.5倍的样子
所以很多使用object的场合 并不一定要换成dyanmic
那么 上面代码中 Test 模仿一下外部加进来的 程序集,在代码执行时 加入的 程序集模块,这种 场景十分常见
这种情况下分两种情况,一种是
有oo设计的 关联的模块,就是 基申明在 调用模块里,比如 基类,或接口等
另一种是,没有oo设计关联的,就是 dynamic的主要价值体现场合,因为在这种情况下 要调用这个模块里的 东西,传统上 只能用object这个 根类通过反映去调用
上面测试对比中已经说明了,与反射 复杂的调用相比,dynamic不仅代码上 简单,而且性能也只有 反射调用的 1/15