2012-04-11 10 views
5

私はちょうど約yield returnを見つけた、私は本当にいいようです。私はこのような方法でそれを使用します。既存のIEnumerableの末尾に値を追加するときの利回り戻り

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を使用して、これを書き換えることは可能ですか?

+0

注意。 –

+0

@EricLippert Hah、確かに。私はいつもこれを間違って綴ります。このケースでは、私は実在のものをまだ取り上げていないので、その検証ルールの例だけです。 – Oliver

答えて

3

あなたはこれをお探しですか?

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" });  
} 

もしそうなら、私は最初のバージョンがよさそうだと思う。

+0

ありがとうございます。 'yield yield 'は必要ですか? – Oliver

+0

いいえ、削除します。 –

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" }); 
    //... 
} 
2

これまでに投稿されたその他のソリューションは良好です。ここにあなたの問題を解決する別の方法があります:

  • 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" }); 
    ... 
} 
関連する問題