【问题标题】:Why ExpandoObject doesn't work properly with Guid converted to string?为什么在将 Guid 转换为字符串时 ExpandoObject 不能正常工作?
【发布时间】:2016-05-09 19:08:21
【问题描述】:

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

【问题讨论】:

  • 你有什么例外吗?
  • 我没有发现任何异常

标签: c# linq lambda expression-trees


【解决方案1】:

GUID 解析最终会得到与仅使用字符串文字相同的字符串(值)。

不同之处在于它在字典中的存储方式:它的类型为Dictionary&lt;string, object&gt;。这意味着将使用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 相同)进行引用相等检查。与使用 value 相比,这显然会返回 false,因为您永远不会创建新对象。

为了使其正常工作,您只需将动态操作数转换为 string,这样它将使用正确的重载:

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

【讨论】:

  • 谢谢@Jeroen Vannevel。有用。也谢谢你的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
相关资源
最近更新 更多