Ger*_*man 3 c# linq lambda expression-trees
如果传递两个字符串,我有一段代码可以正常工作.由于某种原因,如果将GUID转换为字符串,它将无法正常工作.
更详细的说,如果我创建一个新的ExpandoObject并传递字符串值,它可以工作,但如果我将GUID转换为字符串,则不会.
下面的代码应该比较两个参数.在我的例子中,我传递了相同的两个字符串.对于Equal运算符,true如果字符串相同则应该返回.如果第二个参数GUID转换为字符串,则返回false偶数字符串是相同的.dynamicObj.Add(memberName, Guid.Parse(value).ToString());
不知道我错过了什么.这是我的代码.
string value = "642188c7-8e10-e111-961b-0ee1388ccc3b";
string memberName = "State";
string contactValue = value;
var dynamicObj = (IDictionary<string, object>)new ExpandoObject(); dynamicObj.Add(memberName, Guid.Parse(value).ToString());
var expression = Expression.Parameter(typeof(object), "arg");
var binder = Binder.GetMember(CSharpBinderFlags.None, memberName, null, new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
var property = Expression.Dynamic(binder, typeof(object), expression);
var isValid = false;
var right = Expression.Constant(contactValue);
var result = Expression.MakeBinary(ExpressionType.Equal, property, right);
var func = typeof(Func<,>).MakeGenericType(dynamicObj.GetType(), typeof(bool));
var expr = Expression.Lambda(func, result, expression).Compile();
isValid = (bool)expr.DynamicInvoke(dynamicObj);
Run Code Online (Sandbox Code Playgroud)
GUID解析将以与使用字符串文字相同的字符串(值)结束.
然而,区别在于它存储在字典中的方式:它的类型Dictionary<string, object>.这意味着将使用Object其==运算符的类来执行引用相等性检查.在String类,但是,这样做的值相等检查重载这一点.
这就是为什么这会返回true:
Console.WriteLine(value == Guid.Parse(value).ToString());
Run Code Online (Sandbox Code Playgroud)
虽然这返回false:
Console.WriteLine((object) value == (object) Guid.Parse(value).ToString());
Run Code Online (Sandbox Code Playgroud)
由于字符串是不可变的,因此Guid.Parse(value).ToString()将创建一个新string对象并进行引用相等性检查contactValue(与之相同value).false与使用valueall 返回相比,这显然会返回,true因为您从不创建新对象.
为了使它工作,您可以将动态操作数转换为a,string因此它将使用正确的重载:
var castDyn = Expression.Convert(property, typeof(string));
var result = Expression.MakeBinary(ExpressionType.Equal, castDyn, right);
Run Code Online (Sandbox Code Playgroud)