无法将UserQuery枚举转换为枚举

时间:2012-08-13 18:04:24

标签: c# .net linq

我正在尝试执行下面的代码(在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();
}

4 个答案:

答案 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。