以前一直想著有沒有一個方法能夠把字串直接轉化成函式的,剛好有需求就找了下,還真有。
微軟地址:https://docs.microsoft.com/en-us/previous-versions/bb894665(v=msdn.10)?redirectedfrom=MSDN
一、安裝
NuGet程式管理器,System.Linq.Dynamic
二、應用與效能:
class Model { public string name; public Model(string s) { name = s; } } //建立示例資料: Model m1 = new Model("111"); Model m2 = new Model("222"); List<Model> list = new List<Model>(); list.Add(m1); list.Add(m2); //普通Lambda list.Where(m=>m.name.StartsWith("1")).ToList(); //DynamicQuery list.AsQueryable().Where("name.StartsWith(@0) ", "1").ToList();
效果一樣,但效能開銷不同,各執行1000次迴圈:
嘗試其他方法,ParseLambda ,把條件單獨出來獲得函式委託,再呼叫Linq的Where。
var lambda = DynamicExpression.ParseLambda<Model, bool>("name.StartsWith(@0)", "1"); var fun = expfun.Compile(); list.Where(s => fun(s)).ToList();
執行1000次看下,雖然和原生的還有差距,但已經在可以接受的範圍內了。
三、其他方法:
//DynamicExpression中還有CreateClass可以實現類的動態建立: var tp = DynamicExpression.CreateClass(new DynamicProperty("a", typeof(decimal)), new DynamicProperty("b", typeof(decimal))); var obj = Activator.CreateInstance(tp); tp.GetProperty("a").SetValue(obj, 12m,null); tp.GetProperty("b").SetValue(obj, 10m, null); //此時一個包含a,b屬性的例項obj已經建立好,這時利用ParseLambda<T,S>就可以做到很多事情,比如根據字串進行運算。 var lambda = DynamicExpression.ParseLambda(tp,typeof(decimal),"a*b+2"); var fun = lambda.Compile(); decimal sum = (decimal)fun.DynamicInvoke(obj); //其他的比如根據已知型別也可進行一些想要的操作: DynamicExpression.ParseLambda<Model, string>("@0 + name", "名字:");
有時string轉成函式執行還是很方便的,用這個做一個計算器小程式的話,運算子解析什麼的就完全不需要考慮了。
參考連結:
https://www.cnblogs.com/David-Qian/archive/2009/01/22/1379596.html
https://blog.csdn.net/xuchen_wang/article/details/90749743