Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法将UserQuery枚举转换为枚举_C#_.net_Linq - Fatal编程技术网

C# 无法将UserQuery枚举转换为枚举

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

我正在尝试执行下面的代码(在LINQPad中),我的LINQ语句出现错误

无法将类型
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
,因此您的代码从一开始就是假的。