.Net community have frozen in anticipation of C# 7.0 and new features that it brings. Each version of the language that will turn 15 years old next year brought something new and useful for developers. Though each feature worth separate mention, today I want to tell you about keyword yield. I noticed, that beginners (not only) avoid using it. In this article I’ll try to show its pros and cons, and provide cases when yield usage makes sense.

yield creates iterator and lets us do not write separate Enumerator class when we implement IEnumerable. C# has two expressions that contains yield: yield return <expression> ΠΈ yield break. yield can be used in methods, operators or get accessors but I’ll mostly talk about methods as yield works the same way everywhere.

Writing yield return we indicate that current method returns IEnumerable, which elements are results of yield return expressions. After yield method stops its execution it returns control to caller. yield continues execution after next element of sequence is requested. Method variables retains their values between yield return expressions. yield break does well-known role of break which we use in loops. Example below returns numbers sequence from 0 to 10:

private static IEnumerable<int> GetNumbers() {
    var number = 0;
    while (true) {
        if (number > 10)
            yield break;

        yield return number++;
    }
}

It’s important to notice that yield has several constraints. Iterator’s Reset method throws NotSupportedException. We can’t use yield in anonymous methods and methods that have unsafe code. Also, yield return can’t be placed inside try-catch, but can be used in try section of try-finally. yield break can be placed in section try of both try-catch and try-finally. I recommend to read about reasons of such behavior here and here.

Read on β†’

Today I want to share with you a pattern which I use in classic ASP.NET MVC web sites. It solves the problem of filling model* properties that won’t be sent with http request (eg select items). Let’s take a closer look.

Filler sequence diagram

Most of the model properties could be divided into two groups:

  • Domain properties that characterize model
  • Additional properties that describes domain properties
// Some model
public class Account
{
    // Domain property
    public int CountryId { get; set; }
   
    // Additional property
    public IEnumerable<KeyValuePair<int, string>> Countries { get; set; }
}

Domain properties do not require extra logic, they come with http response and we send them within http request. Additional properties, on the contrary, cause a problem because they can’t be sent along with domain properties. Additional properties are not the part of the domain model and could be large. They do not come to application with request and so these properties are empty. As result we can’t validate domain properties using additional properties (like to check if selected Country is one of available Countries). When model has additional properties, they have to be filled during processing form request.

Read on β†’

Any system that receives user input must validate it. ASP.NET MVC applications are not an exception, that is why framework creators implemented several approaches how it could be done. In this article I’m not going into implementation details. Here I want to analyse each of approaches and choose the one which most flexible. Also, I’m not going to touch on the client validation, because I’m sure that it have to be implemented independently from server side. Well, lets look at each of approaches:

Controller validation

Placing validation into controller is the easiest and most direct approach.

public class User
{
    public string Login { get; set; }
    public string Password { get; set; }
}

[HttpPost]
public ActionResult CreateUser(User user) {
    if (string.IsNullOrEmpty(user.Login))
        ModelState.AddModelError("Login", "Please specify Login");

    if (string.IsNullOrEmpty(user.Password))
        ModelState.AddModelError("Password", "Please specify Password");

    if (!ModelState.IsValid)
        return View(user);

    _userService.CreateUser(user);

    return RedirectToAction("UsersList", "Home");
}

We verify model, add errors to ModelState and then just check ModelState.IsValid. This way has obvious advantage - simplicity. We don’t have to isolate logic, any dependencies accessible to controller are also accessible to validator. Logic is easy to find and easy to read. Disadvantages are not less-obvious. Necessity to validate the same model in multiple controllers brings to DRY principle violation. Inability to isolate validation logic leads to troubles in testing. When system complexity arises, disadvantages outweigh the advantages. I could hardly imagine production system where usage of controller validation would be reasonable.

Read on β†’