C# 为什么ExpandoObject没有';Guid转换为字符串时无法正常工作?

C# 为什么ExpandoObject没有';Guid转换为字符串时无法正常工作?,c#,linq,lambda,expression-trees,C#,Linq,Lambda,Expression Trees,如果传递两个字符串,我有一段代码可以正常工作。由于某些原因,如果将GUID转换为字符串,则它的工作方式不同 更详细地说,如果我创建一个新的ExpandoObject并传递字符串值,它会工作,但如果我传递转换为字符串的GUID,它不会工作 下面的代码应该比较两个参数。在我的示例中,我传递相同的两个字符串。使用Equal运算符时,如果字符串相同,则应返回true。如果第二个参数GUID转换为字符串,则返回false即使字符串相同dynamicObj.Add(memberName,Guid.Parse

如果传递两个字符串,我有一段代码可以正常工作。由于某些原因,如果将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);
string value=“642188c7-8e10-e111-961b-0ee1388ccc3b”;
字符串memberName=“State”;
字符串contactValue=值;
var dynamicObj=(IDictionary)new ExpandoObject();dynamicObj.Add(memberName,Guid.Parse(value.ToString());
变量表达式=表达式参数(typeof(object),“arg”);
var binder=binder.GetMember(CSharpBinderFlags.None,memberName,null,new[]{CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None,null)});
var属性=Expression.Dynamic(活页夹、typeof(对象)、表达式);
var isValid=false;
var right=表达式常数(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)表达式DynamicInvoke(dynamicObj);

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

然而,不同之处在于它在字典中的存储方式:它的类型是
dictionary
。这意味着将使用
对象
类及其
=
运算符来执行引用相等性检查。但是,
字符串
类通过执行值相等检查来重载该类

这就是为什么这个结果是正确的:

Console.WriteLine(value == Guid.Parse(value).ToString());
虽然返回false:

Console.WriteLine((object) value == (object) Guid.Parse(value).ToString());
由于字符串是不可变的,
Guid.Parse(value).ToString()
将创建一个新的
string
对象,并与
contactValue
(与
value
相同)进行引用相等性检查。与使用始终返回
true
value
相比,这显然会返回
false
,因为您从未创建新对象

为了使其工作,您可以将动态操作数强制转换为
字符串
,以便它使用正确的重载:

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

你有例外吗?我没有例外谢谢你@Jeroen Vannevel。它起作用了。谢谢你的解释。