C# 无法将UserQuery枚举转换为枚举
我正在尝试执行下面的代码(在LINQPad中),我的LINQ语句出现错误 无法将类型C# 无法将UserQuery枚举转换为枚举,c#,.net,linq,C#,.net,Linq,我正在尝试执行下面的代码(在LINQPad中),我的LINQ语句出现错误 无法将类型System.Collections.Generic.IEnumerable隐式转换为UserQuery.ResultCode 为什么? 代码如下: public enum ResultCode { Big, Bad, Messy } public class ValidationResult { public bool IsValid = false; public R
System.Collections.Generic.IEnumerable
隐式转换为UserQuery.ResultCode
为什么?
代码如下:
public enum ResultCode {
Big,
Bad,
Messy
}
public class ValidationResult {
public bool IsValid = false;
public ResultCode Code;
public override string ToString(){
return String.Format("IsValid: {0}, Code: {1}",IsValid, Code);
}
}
public class RuleMap {
public Func<bool> Fact;
public ResultCode Code;
public List<int> Actions;
}
public class RulesProcessor{
List<RuleMap> rules;
public RulesProcessor(){
rules = new List<RuleMap>{
new RuleMap {Fact = CheckLeft, Code = ResultCode.Big,
Actions = new List<int> {2, 3}
},
new RuleMap {Fact = CheckRight, Code = ResultCode.Bad,
Actions = new List<int> {1, 2}
},
new RuleMap {Fact = CheckDown, Code = ResultCode.Messy,
Actions = new List<int> {1, 3}
},
};
}
public bool CheckLeft(){
return true;
}
public bool CheckRight(){
return false;
}
public bool CheckDown(){
return true;
}
public ValidationResult EvaluateRulesOnAction(int actionType){
ValidationResult result = new ValidationResult();
ResultCode badRule = from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code;
if (badRule != null){
result.Code = badRule;
}else{
result.IsValid = true;
}
return result;
}
}
void Main()
{
var foo = new RulesProcessor();
foo.EvaluateRulesOnAction(1).Dump();
foo.EvaluateRulesOnAction(3).Dump();
}
公共枚举结果代码{
大的
不好,,
凌乱的
}
公共类验证结果{
公共bool IsValid=false;
公共结果代码;
公共重写字符串ToString(){
返回String.Format(“IsValid:{0},代码:{1}”,IsValid,代码);
}
}
公共类规则映射{
公共职能事实;
公共结果代码;
公开名单行动;
}
公共类规则处理器{
列出规则;
公共规则处理程序(){
规则=新列表{
新规则映射{Fact=CheckLeft,Code=ResultCode.Big,
Actions=新列表{2,3}
},
新规则映射{Fact=CheckRight,Code=ResultCode.Bad,
Actions=新列表{1,2}
},
新规则映射{Fact=CheckDown,Code=ResultCode.Messy,
Actions=新列表{1,3}
},
};
}
公共bool CheckLeft(){
返回true;
}
公共bool CheckRight(){
返回false;
}
公共布尔值检查(){
返回true;
}
公共验证结果EvaluateRulesOnAction(int actionType){
ValidationResult=新的ValidationResult();
ResultCode badRule=来自规则中的foo
其中!foo.Fact()&&foo.Actions.Contains(actionType)
选择foo.Code;
如果(badRule!=null){
结果。代码=坏规则;
}否则{
result.IsValid=true;
}
返回结果;
}
}
void Main()
{
var foo=新规则处理器();
foo.evaluaterulesonation(1.Dump();
foo.evaluaterulesonation(3.Dump();
}
将查询更改为如何
IEnumerable<ResultCode> badRule = from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code;
IEnumerable badRule=来自规则中的foo
哪里foo.Fact()&&foo.Actions.Contains(actionType)
选择foo.Code;
并将ValidationResult更改为
public IEnumerable<ResultCode> Code;
公共IEnumerable代码;
原因是表单的每个LINQ查询从x in y select x
返回一个IEnumerable
如果确定最多只能有一条错误规则,则可以将代码更改为:
ResultCode badRule = (from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code).SingleOrDefault();
var badRule = (from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo).FirstOrDefault();
if (badRule != null){
result.Code = badRule.Code;
}else{
result.IsValid = true;
}
如果可能存在多条错误规则,但您只对第一条规则感兴趣,请使用以下方法:
ResultCode badRule = (from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code).FirstOrDefault();
两个查询中的“OrDefault”都表示您希望返回类型的。对于引用类型,这是null
但是,在代码中,查询返回类型为ResultCode
的枚举。枚举不能为null
,因此在查询之后出现的if
将永远不会产生预期的结果,因为badRule==null
总是false
您应该将代码更改为:
ResultCode badRule = (from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code).SingleOrDefault();
var badRule = (from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo).FirstOrDefault();
if (badRule != null){
result.Code = badRule.Code;
}else{
result.IsValid = true;
}
你读到错误了吗 LINQ查询返回结果代码的集合(IEnumerable),而不是单个结果代码。因为:
ResultCode badRule = (from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code).FirstOrDefault();
ResultCode badRule = from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code;
返回一个ResultCodes集合,您正试图将其分配给单个ResultCode变量
如果您知道只有一个结果,那么可以使用First选择它并将其分配给badRule。或者FirstOrDefault,如果可能有1或0个结果。在这种情况下,我想…(从规则中的foo…)FirstOrDefault。。。如果没有,则返回null。那怎么办?当前,当没有规则匹配时,“FirstOrDefault”返回一个非空值。@BrentArias:为什么这样认为?FirstOrDefault特别是在未匹配的情况下返回
null
的版本。更准确地说,它返回default(ResultCode)
,对于引用类型,它是null
。但是,当您返回一个枚举时,它不能是null
,因此您的代码从一开始就是假的。