我正在尝试执行下面的代码(在LINQPad中),我的LINQ语句出错了
无法将
System.Collections.Generic.IEnumerable<UserQuery.ResultCode>
类型隐式转换为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();
}
答案 0 :(得分:0)
如何将查询更改为。
IEnumerable<ResultCode> badRule = from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code;
并将ValidationResult更改为
public IEnumerable<ResultCode> Code;
答案 1 :(得分:0)
原因是from x in y select x
形式的每个LINQ查询都返回IEnumerable<TypeOfX>
。
如果您确定最多可能存在一条错误规则,则可以将代码更改为:
ResultCode badRule = (from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code).SingleOrDefault();
如果可能存在多个错误规则,但您只对第一个规则感兴趣,请使用:
ResultCode badRule = (from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code).FirstOrDefault();
两个查询中的“OrDefault”表示您希望获得返回类型的default value。对于参考类型,这是null
。
但是,在您的代码中,查询返回类型为ResultCode
的枚举。枚举不能为null
,因此查询后的if
永远不会产生预期结果,因为badRule == null
始终为false
。
您应该将代码更改为:
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;
}
答案 2 :(得分:0)
您是否阅读过该错误?
您的LINQ查询返回ResultCodes的集合(IEnumerable),而不是单个ResultCode。
答案 3 :(得分:0)
因为:
ResultCode badRule = from foo in rules
where !foo.Fact() && foo.Actions.Contains(actionType)
select foo.Code;
返回ResultCodes的集合,并尝试将其分配给单个ResultCode变量。
如果您知道只有一个结果,那么您可以使用First选择它并将其分配给badRule。如果可能有1或0个结果,则为FirstOrDefault。