0

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

4 回答 4

0

如何将查询更改为。

        IEnumerable<ResultCode> badRule = from foo in rules
                            where !foo.Fact() && foo.Actions.Contains(actionType)
                            select foo.Code;

并将 ValidationResult 更改为

    public IEnumerable<ResultCode> Code;
于 2012-08-13T18:07:12.693 回答
0

原因是表单的每个 LINQ 查询都from x in y select x返回一个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”表示您希望获得返回类型的默认值。对于引用类型,这是null.

但是,在您的代码中,查询返回一个 enum 类型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;
}
于 2012-08-13T18:07:44.550 回答
0

你读过错误吗?

您的 LINQ 查询返回 ResultCodes 的集合 (IEnumerable),而不是单个 ResultCode。

于 2012-08-13T18:08:04.157 回答
0

因为这:

ResultCode badRule = from foo in rules
                     where !foo.Fact() && foo.Actions.Contains(actionType)
                     select foo.Code;

返回 ResultCodes 的集合,您尝试将其分配给单个 ResultCode 变量。

如果您知道只有一个结果,那么您可以使用 First 选择它并将其分配给 badRule。如果可能有 1 或 0 个结果,则为 FirstOrDefault。

于 2012-08-13T18:08:06.240 回答