生活随笔
收集整理的這篇文章主要介紹了
究竟是什么可以比反射还快实现动态调用?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
戲精分享 C#表達式樹,第一季正式完稿
前不久,我們發布了《只要十步,你就可以應用表達式樹來優化動態調用》。
觀眾們普遍反映文章的內容太多復雜不太容易理解。
因此,我們以此為契機發布了《戲精分享 C#表達式樹》系列視頻?,F在,第一季的視頻已經正式完稿,發布到了 B 站之上。
各位可以前往以下地址來查看內容:https://www.bilibili.com/video/BV15y4y1r7pK
Newbe.ObjectVisitor 0.1.4 現已可用
Newbe.ObjectVisitor 幫助開發者可以用最簡單的最高效的方式訪問一個普通 class 的所有屬性。從而實現:驗證、映射、收集等等操作。
例如, 在你的代碼中有這樣一個簡單的類。
var?order?=?new?OrderInfo();
你想要將這個類所有的屬性和值都打印出來,那么你可以采用反射來完成:
for(var?pInfo?in?typeof(OrderInfo).GetProperties())
{Console.Writeline($"{pInfo.Name}:?{pInfo.GetValue(order)}");
}
如果你使用這個類庫,則可以采用以下方式來實現一樣的效果:
//?call?.V?what?is?a?static?extension?method
//?you?get?a?visitor?object?for?order
var?visitor?=?order.V();visitor.ForEach(context=>{var?name?=?context.Name;var?value?=?context.Value;Console.Writeline($"{name}:?{value}");
}).Run();//?you?can?also?make?it?into?one?line
order.V().ForEach(c=>?Console.Writeline($"{c.Name}:?{c.Value}")).Run();//?or?using?quick?style
order.FormatToString();
那我為什么要這樣做?
因為這樣更快!這個類庫使用表達式樹實現,因此它擁有比直接使用反射快上 10 倍的性能.
因為這樣更可讀!通過這個類庫你可以使用鏈式 API 和命名方法來創建一個委托,這樣可以讓你的代碼實現和硬編碼同樣的可讀效果。
因為這樣更具擴展性!如果使用了這個類庫,你就擁有了一個簡便的方法來訪問一個類所有的屬性。因此,你就做很多你想做的事情,比如:創建一個驗證器來驗證你的模型,修改一些可能包含敏感數據的屬性從而避免輸出到日志中,創建一個類似于 AutoMapper 的對象映射器但是擁有更好的性能,諸如此類。
我們發布了第一個版本。0.1 版本中我們完成了最基礎的 ForEach API,并且實現了 FormatString 方法。
我們對初始版本進行了基準測試。得出了以下結論,詳細的內容也可以前往倉庫首頁查看:
該類庫可以實現和硬編碼一樣快速的性能。
該類庫比直接使用反射更快。
對于非代碼熱點路徑,即使使用非緩存方式調用也仍然在可接受范圍內容。
CacheNoCache
目前,我們還有很多計劃中的 API
iconremark
| ?? | it is already avaliable in latest version |
| ???? | still in plan or development and will be changed or removed |
| ? | it is removed form the latest version |
var?o?=?new?Yueluo();using?Newbe.ObjectVisitor;//???from?0.1
//?V?is?a?static?extension?method
var?visitor?=?o.V();//???from?0.1
//?create?visitor?from?factory?method
var?visitor?=?typeof(Yueluo).V();//???from?0.1
//?create?and?fire?way.
//?this?is?the?most?simple?structure?about?this?lib
//?there?are?Name,?Value,?PropertyInfo,?SourceObj,?SourceObjType?and?etc?in?the?context
o.V().ForEach((context)=>{}).Run();
o.V().ForEach((name,value)=>{}).Run();//???from?0.1
//?create?a?visitor?with?extend?object?as?parameter
o.V().WithExtendObject<Yueluo,?StringBuilder>().ForEach((context)=>{var?_?=?context.ExtendObject}).Run(new?StringBuilder());
o.V().WithExtendObject<Yueluo,?StringBuilder>().ForEach((name,value,stringBuilder)=>{}).Run(new?StringBuilder());//???from?0.1
//?create?and?cache?way.?This?is?suggested?way?to?use.
//?cache?object?visitor?to?run?it?with?anothor?object
var?cachedVisitor?=?deafult(Yueluo).V().ForEach((context)=>{}).Cache();
cachedVisitor.Run(new?Yueluo());//???from?0.1
//?cache?object?visitor?with?extend?object
var?cachedVisitor?=?deafult(Yueluo).V().WithExtendObject<Yueluo,?StringBuilder>().ForEach((context)=>{var?_?=?context.ExtendObject}).Cache();
cachedVisitor.Run(new?Yueluo(),?new?StringBuilder());//?????you?can?modify?value?if?return?a?new?value
o.V().ForEach((context)=>context.Value.SubString(0,1)).Run();//???from?0.1
//?get?debug?info?about?expression?now
var?debugInfo?=?o.V().ForEach((context)=>{}).GetDebugInfo();//?????generate?code?in?C#?as?a?string?about?expression?now
var?code?=?o.V().ForEach((context)=>{}).GenerateCode();//???from?0.1
//?generate?a?lambda?func
var?func?=?o.V().ForEach((context)=>{}).GetLambda();//?????foreach?properties?with?specified?type
o.V().ForEach<string>((context)=>{}).Run();//??????using?linq?to?filter
o.V().AsEnumerable().Where((context)=>context.Name?==?"YueLuo").ForEach((context)=>{}).Run();//??????suppending?visiting?sub?object
o.V().SuppendSubObject().ForEach((context)=>{}).Run();//??????suppending?visiting?enumerable?object
o.V().SuppendEnumerable().ForEach((context)=>{}).Run();/**???from?0.1sample?to?join?all?properties?to?string
*/
var?sb?=?new?StringBuilder();
o.V().ForEach((context)=>{sb.Append(context.Name);sb.Append(context.Value);sb.Append(Enviroment.Newline);
}).Run();
var?s?=?sb.ToString();//???from?0.1
//?quick?style?for?above
var?s?=?o.FormatString();//?????Deconstruct?as?C#?7?but?more?flexible
var?destructor1?=?Destructor<Yueluo>.Property(x=>x.Name).Property(x=>x.Age)var?destructor2?=?Destructor<Yueluo>.Property(x=>x.Name).Property(x=>(long)x.Age)var?destructor3?=?Destructor<Yueluo>.Property(x=>x.Name).Property(x=>x.NickName).Property(x=>x.Age)var?(name,?age)?=?o.V().Destruct(destructor1).Run();
var?(name,?ageInLong)?=?o.V().Destruct(destructor2).Run();
var?(name,?nickName,?age)?=?o.V().Destruct(destructor3).Run();//?namespace?for?operation?with?collections
using?Newbe.ObjectVisitor.Collections;/**????collect?properties?into?a?dictionary
*/var?dic1?=?o.V().CollectAsDictionary().Run();
//?quick?style?for?above
var?dic1?=?o.V().ToDictionary();/**????apply?value?from?a?dictionary?to?object
*/
o.V().ApplyFromDictionary(dic).Run();
//?quick?style?for?above
o.V().FromDictionary(dic);//?namespace?for?data?validation
using?Newbe.ObjectVisitor.Validation;//?????create?rule?to?validation
var?rule?=?ValidateRule<Yueluo>.GetBuilder().Property(x=>x.Name).Required().Length(2,10).Property(x=>x.Age).Range(0,?int.MaxValue).Property(x=>x.Password).Validate(value=>ValidatePassword(value)).Property(x=>x.Level).Validate(value=>value?+?1?>=?0).Build();o.V().Validate(rule).Run();
o.Validate(rule);//?????validate?data?in?flunet?api
//?attribute-based?enabled?by?default
o.V().Validate(v=>v.Property(x=>x.Name).Required().Length(2,10).Property(x=>x.Age).Range(0,?int.MaxValue).Property(x=>x.Password).Validate(value=>ValidatePassword(value)).Property(x=>x.Level).Validate(value=>value?+?1?>=?0)
).Run();//?????suppending?attribute-based?validation
o.V().SuppendAttributeValidation().Validate(v=>v.Property(x=>x.Name).Required().Length(2,10).Property(x=>x.Age).Range(0,?int.MaxValue).Property(x=>x.Password).Validate(value=>ValidatePassword(value)).Property(x=>x.Level).Validate(value=>value?+?1?>=?0)
).Run();//?????suppending?sub-object?validation
//?validate?whole?object
o.V().SuppendSubObject().SuppendAttributeValidation().Validate(v=>v.Validate(x=>x.NewPassword?==?x.OldPassword).Validate(x=>ValidateFormDb(x)).Property(x=>x.Name).Required().Length(2,10).Property(x=>x.Age).Range(0,?int.MaxValue).Property(x=>x.Age).If(x=>x.Name?==?"123").Range(0,?int.MaxValue).Property(x=>x.Password).Validate(value=>ValidatePassword(value)).Property(x=>x.Level).Validate(value=>value?+?1?>=?0)
).Run();//?namespace?for?Task
using?Newbe.ObjectVisitor.Task;//?????async?way
await?o.V().ForEachAsync((context)=>{}).RunAsync();//?????controlling?concurrency
await?o.V().ForEachAsync((context)=>{}).WhenAsync(tasks=>Task.WhenAll(tasks)).RunAsync();//?namespace?for?Microsoft.Extensions.DependencyInjection
using?Newbe.ObjectVistory.DepencyInjection;//?????inject?services?to?the?properties?of?this?object
this.V().ForEach(context=>this.ServiceProvider.GetService(context.PropertyInfo.PorpertyType)).Run();//?????quick?style?for?above
this.V().PropertyInject(this.ServiceProvider);
總結
以上是生活随笔為你收集整理的究竟是什么可以比反射还快实现动态调用?的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。