6

を知ったばかりですがyield return、私はとてもいい人に見えます。私は次のような方法でそれを使用します:

public IEnumerable<ValidationResult> Validate(ValidationContext vc)
{
    if (Name == "Arbitary")
        yield return new ValidationResult("Bad Name.", new[] { "Name" });
    else if (Email == "BadEmail")
        yield return new ValidationResult("Bad Email.", new [] {"Email" });
    // further rules follow.
}

ただし、子メソッドからいくつかの ValidationResults を返すように、このメソッドを変更する必要があります。を使用しない場合yield、コードは次のようになります。

public override IEnumerable<ValidationResult> Validate(ValidationContext vc)
{
    // TryValidateObject fills the ICollection you pass it.
    List<ValidationResult> retVal = new List<ValidationResult>();
    Validator.TryValidateObject(this, vc, retVal, true);

    if (Name == "Arbitary")
        retVal.Add(new ValidationResult("Bad Name.", new[] { "Name" }));
    else if (Email == "BadEmail")
        retVal.Add(new ValidationResult("Bad Email.", new[] { "Email" }));

    return retVal;
}

を使用してこれを書き換えることは可能yieldですか?

4

3 に答える 3

4

これをお探しですか?

public override IEnumerable<ValidationResult> Validate(ValidationContext vc)
{
    // TryValidateObject fills the ICollection you pass it.
    List<ValidationResult> retVal = new List<ValidationResult>();
    Validator.TryValidateObject(this, vc, retVal, true);
    foreach (var item in retVal)
        yield return item;
    if (Name == "Arbitary")
        yield return new ValidationResult("Bad Name.", new[] { "Name" });
    else if (Email == "BadEmail")
        yield return new ValidationResult("Bad Email.", new[] { "Email" });       
}

もしそうなら、私は最初のバージョンがより良く見えると信じています。

于 2012-04-11T11:54:34.650 に答える
3

これまでに投稿された他の解決策は良いです。問題を解決する別の方法は次のとおりです。

  • 2つのシーケンスを作成する
  • それらを連結します
  • 連結を返します。

それで:

public override IEnumerable<ValidationResult> Validate(ValidationContext vc)
{
  return ResultsFromValidator(vc).Concat(AdditionalResults());
}
private IEnumerable<ValidationResult> ResultsFromValidator(ValidationContext vc)
{
  List<ValidationResult> retVal = new List<ValidationResult>();
  Validator.TryValidateObject(this, vc, retVal, true);
  return retVal;
}
private IEnumerable<ValidationResult> AdditionalResults()
{
  if (Name == "Arbitrary")
    yield return new ValidationResult("Bad Name.", new[] { "Name" });
  ...
}
于 2012-04-11T15:03:37.337 に答える
2

もちろん。これを使用してください:

foreach (var item in retVal) {
    yield return item;
}

その後、イールドリターンを続行することもできます。したがって、メソッドを呼び出した後にretValを返し、最初のサンプルと同じように続行できます。このような:

public override IEnumerable<ValidationResult> Validate(ValidationContext vc)
{
    List<ValidationResult> retVal = new List<ValidationResult>();
    Validator.TryValidateObject(this, vc, retVal, true);
    foreach (var item in retVal) {
        yield return item;
    }

    if (Name == "Arbitary")
        yield return new ValidationResult("Bad Name.", new[] { "Name" });
    else if (Email == "BadEmail")
        yield return new ValidationResult("Bad Email.", new[] { "Email" });
    //...
}
于 2012-04-11T11:54:18.267 に答える