日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

反射,Expression Tree,IL Emit 属性操作对比

發布時間:2025/3/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 反射,Expression Tree,IL Emit 属性操作对比 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • .net的反射(Reflection) 是.Net中獲取運行時類型信息的一種方法,通過反射編碼的方式可以獲得 程序集,模塊,類型,元數據等信息。
    反射的優點在于微軟提供的API調用簡單,使用方便;

  • 表達式樹(Expression Tree)表達式樹以樹形數據結構表示代碼,其中每一個節點都是一種表達式,表達式樹經過編譯后生成的直接是IL代碼;

  • IL Emit 是直接操作IL的執行過程,對IL代碼精細化控制;

屬性賦值操作 PropertyInfo.GetValue/SetValue是反射中常用的功能;
三種實現方式的性能對比:

public class Bar{public int Id { get; set; }public string Name { get; set; }}public class Foo{public Bar Bar { get; set; }public static void SetReflection(Foo foo, Bar bar){var property = foo.GetType().GetProperty("Bar");property.SetValue(foo, bar);}public static Action<Foo, Bar> SetExpression(){var property = typeof(Foo).GetProperty("Bar");var target = Expression.Parameter(typeof(Foo));ParameterExpression propertyValue = Expression.Parameter(typeof(Bar));//var setPropertyValue = Expression.Call(target, property.GetSetMethod(), propertyValue);BinaryExpression setPropertyValue = Expression.Assign(Expression.Property(target, property), propertyValue);var setAction = Expression.Lambda<Action<Foo, Bar>>(setPropertyValue, target, propertyValue).Compile();return setAction;}public static Action<Foo, Bar> SetEmit(){var property = typeof(Foo).GetProperty("Bar");DynamicMethod method = new DynamicMethod("SetValue", null, new Type[] { typeof(Foo), typeof(Bar) });ILGenerator ilGenerator = method.GetILGenerator();ilGenerator.Emit(OpCodes.Ldarg_0);ilGenerator.Emit(OpCodes.Ldarg_1);ilGenerator.EmitCall(OpCodes.Callvirt, property.GetSetMethod(), null);ilGenerator.Emit(OpCodes.Ret);method.DefineParameter(1, ParameterAttributes.In, "obj");method.DefineParameter(2, ParameterAttributes.In, "value");var setAction2 = (Action<Foo, Bar>)method.CreateDelegate(typeof(Action<Foo, Bar>));return setAction2;}public static void Test(){var act1 = Foo.SetExpression();var act2 = Foo.SetEmit();var st = new Stopwatch();st.Start();for (int i = 0; i < 1000000; i++){var foo = new Foo { };var bar = new Bar { Id = 1, Name = "name" };Foo.SetReflection(foo, bar);}Console.WriteLine("Reflection " + st.ElapsedMilliseconds);st.Restart();for (int i = 0; i < 1000000; i++){var foo = new Foo { };var bar = new Bar { Id = 1, Name = "name" };act1(foo, bar);}Console.WriteLine("Expression " + st.ElapsedMilliseconds);st.Restart();for (int i = 0; i < 1000000; i++){var foo = new Foo { };var bar = new Bar { Id = 1, Name = "name" };act2(foo, bar);}Console.WriteLine("Emit " + st.ElapsedMilliseconds);}}

循環多次操作性能對比還是明顯的表達式數和emit的性能優勢明顯;
測試結果

但是只循環一次的話 三種實現方式性能是無差別的,所以在一般情況下,反射的性能損失是可以忽略的;

轉載于:https://www.cnblogs.com/sands/p/11373569.html

總結

以上是生活随笔為你收集整理的反射,Expression Tree,IL Emit 属性操作对比的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。