如何解决C#是否有DataBinder.Eval的快速版本?
| 我正在寻找是否存在ASP.NET的System.Web.UI.DataBinder.Eval()的快速版本? 理想情况下,可以编译为Func的东西可以稍后缓存并调用,例如:Func<object,string> expr = CompileDataBinder(typeof(Model),\"model.Pocoproperty.Name\");
string propertyName = expr(model);
有人知道这种野兽是否存在吗?
附言我没有使用ASP.NET,并且希望它能在正常的C#中工作
解决方法
我看的越多,我想说的越多:
Func<Model,string> expr = model => model.PocoProperty.Name;
如果您需要基于字符串的字符串,那么Expression
API很公平。
class Program
{
static void Main(string[] args)
{
Func<object,string> expr = CompileDataBinder(typeof(Model),\"PocoProperty.Name\");
var model = new Model { PocoProperty = new ModelPoco { Name = \"Foo\" } };
string propertyName = expr(model);
}
static Func<object,string> CompileDataBinder(Type type,string expr)
{
var param = Expression.Parameter(typeof(object));
Expression body = Expression.Convert(param,type);
var members = expr.Split(\'.\');
for (int i = 0; i < members.Length;i++ )
{
body = Expression.PropertyOrField(body,members[i]);
}
var method = typeof(Convert).GetMethod(\"ToString\",BindingFlags.Static | BindingFlags.Public,null,new Type[] { body.Type },null);
if (method == null)
{
method = typeof(Convert).GetMethod(\"ToString\",new Type[] { typeof(object)},null);
body = Expression.Call(method,Expression.Convert(body,typeof(object)));
}
else
{
body = Expression.Call(method,body);
}
return Expression.Lambda<Func<object,string>>(body,param).Compile();
}
}
class Model
{
public ModelPoco PocoProperty { get; set; }
}
class ModelPoco
{
public string Name { get; set; }
}
,以下是一些应该帮助您入门的内容:
using System;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
class Person
{
public int Id { get; set; }
public FullName FullName { get; set; }
}
class FullName
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
class Program
{
static void Main(string[] args)
{
Person model = new Person
{
Id = 123,FullName = new FullName
{
FirstName = \"Duncan\",LastName = \"Smart\",}
};
var nameBinder = CompileDataBinder<Person,string>(\"model.FullName.FirstName\");
string fname = nameBinder(model);
Debug.Assert(fname == \"Duncan\");
// Note how here we pretend we don\'t know TProp type
var idBinder = CompileDataBinder<Person,object>(\"model.Id\");
object id = idBinder(model);
Debug.Assert(id.Equals(123));
}
static Func<TModel,TProp> CompileDataBinder<TModel,TProp>(string expression)
{
var propNames = expression.Split(\'.\');
var model = Expression.Parameter(typeof(TModel),\"model\");
Expression body = model;
foreach (string propName in propNames.Skip(1))
body = Expression.Property(body,propName);
//Debug.WriteLine(prop);
if (body.Type != typeof(TProp))
body = Expression.Convert(body,typeof(TProp));
Func<TModel,TProp> func = Expression.Lambda<Func<TModel,TProp>>(body,model).Compile();
//TODO: cache funcs
return func;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。