编程语言
首页 > 编程语言> > c#-比较两个枚举值的Linq表达式

c#-比较两个枚举值的Linq表达式

作者:互联网

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

expr = Expression.GreaterThanOrEqual(memberExpression, constExpression);

直到memberExpression和constExpression为MyEnum类型时,此方法才能正常工作.这会引发运行时错误:

The binary operator GreaterThanOrEqual is not defined for the types ‘MyNamespace.MyEnum’ and ‘MyNamespace.MyEnum’.

我可以通过将枚举值转换为整数来解决此问题,但这似乎是错误的.如果我可以在C#中的MyEnum值之间进行比较操作,那么“表达式”构建器为什么不允许它?

解决方法:

I could get around it some other place by converting the enum values
to integers, but that seems wrong, somehow.

它应该不会错.毕竟,这就是编译器本身所做的工作-要么用枚举值代替其对应的数值(当在编译时知道枚举值时),要么生成在运行时执行必要强制转换的代码.请注意,这些强制类型转换不一定是int,而是所涉及枚举的后备类型.

If I can do a comparative operation between MyEnum values in C#, then
why doesn’t the Expression builder allow it?

您正在构建的表达式树看起来与C#代码中发生的事情相匹配,但实际上却不匹配-正是由于编译器如上所述在幕后所做的事情.

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

但是,这样做将意味着失去表达式树的WYSIWYG属性:您将认为您正在生成表达式树X,而实际上您将生成其他表达式树Y.

这可能是完全理想的-并且您当然可以编写自己的方法来执行此操作-但这不是一个好主意,因为默认行为(通常C#的设计避免了DWIM的心态),并且/或者不能证明开发成本是合理的.请记住,在很多地方,编译器都会进行繁重的工作,因此仅容纳这些方案的一部分是任意的,而容纳所有方案则可能是禁止的.看看Roslyn的可用性是否会更改此评估会很有趣.

标签:linq-to-entities,c
来源: https://codeday.me/bug/20191122/2056118.html