繁体   English   中英

为什么在Guid转换为字符串时,ExpandoObject无法正常工作?

[英]Why ExpandoObject doesn't work properly with Guid converted to string?

如果传递两个字符串,我有一段代码可以正常工作。 由于某种原因,如果将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);

GUID解析将以与使用字符串文字相同的字符串(值)结束。

然而,区别在于它存储在字典中的方式:它的类型为Dictionary<string, object> 这意味着将使用Object类的==运算符来执行引用相等性检查。 但是, String类通过执行值相等性检查来重载它。

这就是为什么这会返回true:

Console.WriteLine(value == Guid.Parse(value).ToString());

虽然这返回false:

Console.WriteLine((object) value == (object) Guid.Parse(value).ToString());

由于字符串是不可变的, Guid.Parse(value).ToString()将创建一个新string对象,并做比较的参考相等性检查contactValue (其是相同的value )。 这显然将返回false相比,使用value都沿着它返回true ,因为你从来没有创建新的对象。

为了使它工作,您可以将动态操作数转换为string以便它将使用正确的重载:

var castDyn = Expression.Convert(property, typeof(string));
var result = Expression.MakeBinary(ExpressionType.Equal, castDyn, right);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM