所以我有一种情况需要根据包含的值动态更新对象的属性。在下面的例子中,我需要更新值,如果condition为true,则用不同的字符串替换当前值的前两个字符。
PersonDetail.EvaluateConditionalRule("ID",
"((ID.Length > Convert.ToInt32(@0) ) AND ID.Substring(Convert.ToInt32(@1), Convert.ToInt32(@2)) == @3 )",
new[] { "1", "0", "2", "SS" }, " ID = (@0 + ID.Substring(Convert.ToInt32(@1))) " , new[] { "98", "2" });
public static void EvaluateConditionalRule(this PersonDetail Detail, String PropertyToEvaluate,
String ConditionalExpression, String[] parameters, String IfTrueExpression,String[] IfTrueExpreassionparameters )
{
var property = Detail.GetType().GetProperties().Where(x => x.Name == PropertyToEvaluate).FirstOrDefault();
if (property == null)
throw new InvalidDataException(String.Format("Please specify a valid {0} property name for the evaluation.", Detail.GetType()));
//put together the condition like so
if (new[] { Detail }.AsQueryable().Where(ConditionalExpression, parameters).Count() > 0 && IfTrueExpression != null)
{
var result = new[] { Detail }.AsQueryable().Select(IfTrueExpression, IfTrueExpreassionparameters);
//Stuck Here as result does not contain expected value
property.SetValue( Detail,result , null);
}
}
基本上我想要的是,能够执行这个表达式,并且我认为我没有正确的子串替换表达式的格式来正确评估。我想从上面得到的是像
ID = "98"+ ID.Substring(2);
任何帮助将不胜感激。感谢
答案 0 :(得分:0)
不确定你的意思是什么意思“动态”但我认为使用lambdas的方法并不适合你:
static void Main(string[] args) {
User user = new User { ID = 5, Name = "Test" };
SetNewValue(user, u => u.Name, s => s.StartsWith("T"), s => s + "123");
}
static void SetNewValue<TObject, TProperty>(TObject obj, Func<TObject, TProperty> propertyGetter, Func<TProperty, bool> condition, Func<TProperty, TProperty> modifier) {
TProperty property = propertyGetter(obj);
if (condition(property)) {
TProperty newValue = modifier(property);
//set via reflection
}
}
所以我建议您使用Expression trees,它允许您构建您喜欢的任何运行时构造,部分示例
var exp = Expression.Call(Expression.Constant("test"), typeof(string).GetMethod("Substring", new[] { typeof(int) }), Expression.Constant(2));
Console.WriteLine(Expression.Lambda(exp).Compile().DynamicInvoke()); //prints "st"
但是,如果要将带有原始c#代码的字符串用作表达式,请检查CSharpCodeProvider类
答案 1 :(得分:0)
请向我们提供一些有关您为何需要更新此动态的信息。您是否希望用户手动输入条件字符串?
关于您的代码:
您的选择器字符串错误。在LINQ动态查询库中有一个特殊的语法。请在随文档提供的文档(请参阅表达式语言和数据对象初始化程序)中查找:http://msdn.microsoft.com/en-US/vstudio/bb894665.aspx
我写了一个小样本:
var id = new string[] { "SS41231" }.AsQueryable();
// *it* represents the current element
var res = id.Where("it.Length > @0 AND it.Substring(@1, @2) = @3", 1, 0, 2, "SS"); // Save the result, don't throw it away.
if (res.Any())
{
// Line below in normal LINQ: string newID = res.Select(x => "98" + x.Substring(2)).First();
string newId = res.Select("@0 + it.Substring(@1)", "98", 2).Cast<string>().First();
Console.WriteLine(newId);
}
请写一些反馈。
问候。