Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于比较两个枚举值的Linq表达式_C#_Linq To Entities - Fatal编程技术网

C# 用于比较两个枚举值的Linq表达式

C# 用于比较两个枚举值的Linq表达式,c#,linq-to-entities,C#,Linq To Entities,我正在我的应用程序中进行一些表达式构建,大部分时间都在运行。但当我尝试对枚举值进行比较运算时,遇到了麻烦。例如: expr = Expression.GreaterThanOrEqual(memberExpression, constExpression); 在memberExpression和constExpression属于MyEnum类型之前,此功能正常工作;这会引发运行时错误: 未为类型“MyNamespace.MyEnum”和“MyNamespace.MyEnum”定义二进制运算符G

我正在我的应用程序中进行一些表达式构建,大部分时间都在运行。但当我尝试对枚举值进行比较运算时,遇到了麻烦。例如:

expr = Expression.GreaterThanOrEqual(memberExpression, constExpression);
memberExpression
constExpression
属于
MyEnum
类型之前,此功能正常工作;这会引发运行时错误:

未为类型“MyNamespace.MyEnum”和“MyNamespace.MyEnum”定义二进制运算符GreaterThanOrEqual


通过将枚举值转换为整数,我可以在其他地方绕过它,但不知何故,这似乎是错误的。如果我可以在C#中的
MyEnum
值之间进行比较操作,那么为什么表达式生成器不允许这样做


我可以通过转换枚举值在其他地方绕过它 对于整数,但不知何故,这似乎是错误的

感觉应该没错。毕竟,编译器本身就是这样做的——它要么用枚举值替换相应的数值(当枚举值在编译时已知时),要么生成代码,在运行时执行必要的强制转换。请注意,这些强制转换不一定是针对
int
,而是针对所讨论的枚举的支持类型

如果我可以在C#中的
MyEnum
值之间进行比较运算,那么 为什么
表达式
生成器不允许它

您正在构建的表达式树看起来与C#代码中发生的事情相匹配,但实际上并不匹配——这正是因为编译器在上面提到的幕后所做的事情

确实,没有任何技术原因导致
Expression.GreaterThanOrEqual
和friends无法检查其参数并生成与编译器所做操作完全相同的表达式树。例如,如果传入两个
ConstantExpression
s,且
Type
等于
MyEnum
,则该方法可以使用反射来确定与其参数相对应的数值,其行为就像传入了该类型的常量表达式,而不是抛出。它还可以处理一般情况(非常量子表达式)

但是,这样做将意味着表达式树的WYSIWYG属性丢失:您可能会认为您正在生成表达式树X,而实际上您将生成不同的表达式树Y


这可能是非常理想的——您当然可以编写自己的方法来实现这一点——但这可能不是一个好主意,因为默认行为(一般来说,C#的设计避开了这种心态)和/或无法证明开发成本是合理的。请记住,在很多地方,编译器在看不见的情况下执行繁重的工作,因此只适应这些场景的一个子集是任意的,而适应所有场景可能是禁止的。很有意思的是,看看这个评估的可用性是否会改变。

我最终没有转换成整数

private static void Example(string value, Type type, ParameterExpression pe, string propertyName)
{
    Expression whereValue = null;
    if (type.IsEnumOrNullableEnum())
    {
        whereValue = Expression.Constant(Enum.Parse(type, value));
    }
    Expression propExp = Expression.Property(pe, propertyName);
    Expression ruleExpression = Expression.Equal(propExp, whereValue);//results in: item.MyEnum = A
}

可能是因为比较运算符强制转换为整数?“我可以通过将枚举值转换为整数来绕过它,但这似乎是错误的”=>为什么?枚举只不过是“带标签的数字”。显然,当你想比较这些值时,你就要比较数字。@Jon,我的观点正是这样;如果枚举只是带标签的数字,为什么
表达式.GreaterThanOrEqual
会失败?@Shaul:我想这是因为在编写实时代码时,编译器会自动用值替换标签,而在构建表达式树时,您正处于完全手动模式:您编写的内容就是发生的,不会更多,也不会更少。因此,在编译时,
Foo.Bar
被翻译成
2<3
,但在表达式树中,您会得到两个
Foo
类型的值,并且该类型没有定义小于运算符。@Shaul:当然,如果您有非恒定表达式,编译器会插入所需的强制转换(不能强制转换为
int
,枚举也可以由其他类型支持)自动地,在表达式方面再次这样做会导致中等复杂的子树。如果
Expression.GreaterThanOrEqual
以这种方式工作,你会认为你在添加一个节点,但在幕后你会添加一大堆东西。