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>です。

最大で1つの不正なルールが存在する可能性があることが確実な場合は、コードを次のように変更できます。

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です。

ただし、コードでは、クエリはタイプの列挙型を返しますResultCode。列挙型を。にすることはできないnullため、クエリの後に続く列挙型は、いつもifのように期待される結果をもたらすことはありません。badRule == nullfalse

コードを次のように変更する必要があります。

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クエリは、単一のResultCodeではなく、ResultCodesのコレクション(IEnumerable)を返します。

于 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変数に割り当てようとしています。

結果が1つしかないことがわかっている場合は、Firstを使用して結果を選択し、badRuleに割り当てることができます。または、結果が1または0の場合は、FirstOrDefault。

于 2012-08-13T18:08:06.240 に答える