I am doing the Nerd Dinner tutorial for ASP.NET MVC and I met one construction in the C# language that seemed very strange. The title of this question is a bit vague, because I have trouble defining what this is. This also made it difficult for me to search about the topic, hence I decide to ask a question about it.
In the Nerd Dinner tutorial I see the following code fragment:
public static class ControllerHelpers {
public static void AddRuleViolations(this ModelStateDictionary modelState, IEnumerable<RuleViolation> errors) {
foreach (RuleViolation issue in errors) {
modelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}
}
}
And later they show:
//
// GET: /Dinners/Edit/2
public ActionResult Edit(int id) {
Dinner dinner = dinnerRepository.GetDinner(id);
return View(dinner);
}
//
// POST: /Dinners/Edit/2
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues) {
Dinner dinner = dinnerRepository.GetDinner(id);
try {
UpdateModel(dinner);
dinnerRepository.Save();
return RedirectToAction("Details", new { id=dinner.DinnerID });
}
catch {
ModelState.AddRuleViolations(dinner.GetRuleViolations());
return View(dinner);
}
}
The parts that puzzle me are:
public static void AddRuleViolations(this ModelStateDictionary modelState, IEnumerable<RuleViolation> errors)
and
ModelState.AddRuleViolations(dinner.GetRuleViolations());
It looks like you define the AddRuleViolations function in the ControllerHelpers class and then invoke it as if it was an instance function of the ModelState property. Is this observation correct? If yes, why would you need this? It looks very strange to me to define a method in one class as if it was a method of another class.
Note: ModelState is a property of the current class and not a class it self.
It’s because it’s an extension method. That’s what the “this” bit is at the start of the first parameter.
The idea of extension methods is that they allow you to effectively add functionality to existing classes. So if you have:
then you can call it like this:
that actually gets compiled as if you’d written:
Extension methods have to be declared in top-level non-generic static classes. They’re heavily used in LINQ.