Listing 4-1. The Initial Content of the Home Controller
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } } }
Listing 4-2. The Contents of the Result View File
@model String @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Result</title> </head> <body> <div> @Model </div> </body> </html>
Listing 4-3. Defining a Property
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace LanguageFeatures.Models { public class Product { private string name; public string Name { get { return name; } set { name = value; } } } }
Listing 4-4. Consuming a Property
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } public ViewResult AutoProperty() { Product product = new Product(); product.Name = "Kayak"; string productName = product.Name; return View("Result", (object)String.Format("Product name: {0}", productName)); } } }
Listing 4-5. Verbose Property Definitions
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace LanguageFeatures.Models { public class Product { private int productId; private string name; private string description; private decimal price; private string category; public int ProductId { get { return productId; } set { productId = value; } } public string Name { get { return name; } set { name = value; } } public string Description { get { return description; } set { description = value; } } public decimal Price { get { return price; } set { price = value; } } public string Category { get { return category; } set { category = value; } } } }
Listing 4-6. Using Automatically Implemented Properties
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace LanguageFeatures.Models { public class Product { public int ProductId { get; set; } public string Name { get; set; } public string Description { get; set; } public decimal Price { get; set; } public string Category { get; set; } } }
Listing 4-7. Reverting from an Automatic to a Regular Property
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace LanguageFeatures.Models { public class Product { private string name; public int ProductId { get; set; } public string Name { get { return ProductId + name; } set { name = value; } } public string Description { get; set; } public decimal Price { get; set; } public string Category { get; set; } } }
Listing 4-8. Constructing and Initializing an Object with Properties
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } public ViewResult AutoProperty() { Product product = new Product(); product.Name = "Kayak"; string productName = product.Name; return View("Result", (object)String.Format("Product name: {0}", productName)); } public ViewResult CreateProduct() { Product product = new Product(); product.ProductId = 100; product.Name = "Kayak"; product.Description = "A boat for one person"; product.Price = 275M; product.Category = "Watersports"; return View("Result", (object)String.Format("Category: {0}", product.Category)); } } }
Listing 4-9. Using the Object Initializer Feature
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } public ViewResult AutoProperty() { Product product = new Product(); product.Name = "Kayak"; string productName = product.Name; return View("Result", (object)String.Format("Product name: {0}", productName)); } public ViewResult CreateProduct() { Product product = new Product { ProductId = 100, Name = "Kayak", Description = "A boat for one person", Price = 275M, Category = "Waterports" }; return View("Result", (object)String.Format("Category: {0}", product.Category)); } } }
Listing 4-10. Initializing Collections and Arrays
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } public ViewResult AutoProperty() { Product product = new Product(); product.Name = "Kayak"; string productName = product.Name; return View("Result", (object)String.Format("Product name: {0}", productName)); } public ViewResult CreateProduct() { Product product = new Product { ProductId = 100, Name = "Kayak", Description = "A boat for one person", Price = 275M, Category = "Waterports" }; return View("Result", (object)String.Format("Category: {0}", product.Category)); } public ViewResult CreateCollection() { string[] stringArray = { "apple", "orange", "plum"}; List<int> intList = new List<int> { 10, 20, 30, 40 }; Dictionary<string, int> dict = new Dictionary<string, int> { { "apple", 10 }, { "orange", 20 }, { "plum", 30 } }; return View("Result", (object)stringArray[1]); } } }
Listing 4-11. The ShoppingCart Class
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace LanguageFeatures.Models { public class ShoppingCart { public List<Product> Products { get; set; } } }
Listing 4-12. Defining an Extension Method
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace LanguageFeatures.Models { public static class MyExtensionMethods { public static decimal TotalPrices(this ShoppingCart cart) { decimal total = 0; foreach (Product prod in cart.Products) { total += prod.Price; } return total; } } }
Listing 4-13. Applying an Extension Method
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } // Other action methods omitted for brevity public ViewResult UseExtension() { // Create and populate ShoppingCart ShoppingCart cart = new ShoppingCart { Products = new List<Product> { new Product{Name = "Kayak", Price = 275M}, new Product{Name = "Lifejacket", Price = 48.95M}, new Product{Name = "Soccer ball", Price = 19.50M}, new Product{Name = "Corner flag", Price = 34.95M} } }; // Get the total value of the products in the cart decimal cartTotal = cart.TotalPrices(); return View("Result", (object)String.Format("Total: {0:c}", cartTotal)); } } }
Listing 4-14. Implementing an Interface in the ShoppingCart Class
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Web; namespace LanguageFeatures.Models { public class ShoppingCart : IEnumerable<Product> { public List<Product> Products { get; set; } public IEnumerator<Product> GetEnumerator() { return Products.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }
Listing 4-15. An Extension Method That Works on an Interface
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace LanguageFeatures.Models { public static class MyExtensionMethods { public static decimal TotalPrices(this IEnumerable<Product> productEnum) { decimal total = 0; foreach (Product prod in productEnum) { total += prod.Price; } return total; } } }
Listing 4-16. Applying an Extension Method to Different Implementations of the Same Interface
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } // Other action methods omitted for brevity public ViewResult UseExtensionEnumerable() { IEnumerable<Product> products = new ShoppingCart { Products = new List<Product> { new Product{Name = "Kayak", Price = 275M}, new Product{Name = "Lifejacket", Price = 48.95M}, new Product{Name = "Soccer ball", Price = 19.50M}, new Product{Name = "Corner flag", Price = 34.95M} } }; Product[] productArray = { new Product{Name = "Kayak", Price = 275M}, new Product{Name = "Lifejacket", Price = 48.95M}, new Product{Name = "Soccer ball", Price = 19.50M}, new Product{Name = "Corner flag", Price = 34.95M} }; decimal cartTotal = products.TotalPrices(); decimal arrayTotal = productArray.TotalPrices(); return View("Result", (object)String.Format("Cart Total: {0}, Array Total: {1}", cartTotal, arrayTotal)); } } }
Listing 4-17. A Filtering Extension Method
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace LanguageFeatures.Models { public static class MyExtensionMethods { public static decimal TotalPrices(this IEnumerable<Product> productEnum) { decimal total = 0; foreach (Product prod in productEnum) { total += prod.Price; } return total; } public static IEnumerable<Product> FilterByCategory( this IEnumerable<Product> productEnum, string category) { foreach (Product prod in productEnum) { if (prod.Category == category) { yield return prod; } } } } }
Listing 4-18. Using the Filtering Extension Method
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } // Other action methods omitted for brevity public ViewResult UseFilterExtensionMethod() { IEnumerable<Product> products = new ShoppingCart { Products = new List<Product> { new Product{Name = "Kayak", Category = "Watersports", Price = 275M}, new Product{Name = "Lifejacket", Category = "Watersports", Price = 48.95M}, new Product{Name = "Soccer ball", Category = "Soccer", Price = 19.50M}, new Product{Name = "Corner flag", Category = "Soccer", Price = 34.95M} } }; decimal total = 0; foreach (Product prod in products.FilterByCategory("Soccer")) { total += prod.Price; } return View("Result", (object)String.Format("Total: {0}", total)); } } }
Listing 4-19. Using a Delegate in an Extension Method
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace LanguageFeatures.Models { public static class MyExtensionMethods { public static decimal TotalPrices(this IEnumerable<Product> productEnum) { decimal total = 0; foreach (Product prod in productEnum) { total += prod.Price; } return total; } public static IEnumerable<Product> FilterByCategory( this IEnumerable<Product> productEnum, string category) { foreach (Product prod in productEnum) { if (prod.Category == category) { yield return prod; } } } public static IEnumerable<Product> Filter( this IEnumerable<Product> productEnum, Func<Product, bool> selector) { foreach (Product prod in productEnum) { if (selector(prod)) { yield return prod; } } } } }
Listing 4-20. Using the Filtering Extension Method with a Func
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } // Other action methods omitted for brevity public ViewResult UseFilterExtensionMethod() { IEnumerable<Product> products = new ShoppingCart { Products = new List<Product> { new Product{Name = "Kayak", Category = "Watersports", Price = 275M}, new Product{Name = "Lifejacket", Category = "Watersports", Price = 48.95M}, new Product{Name = "Soccer ball", Category = "Soccer", Price = 19.50M}, new Product{Name = "Corner flag", Category = "Soccer", Price = 34.95M} } }; Func<Product, bool> categoryFilter = delegate(Product prod) { return prod.Category == "Soccer"; }; decimal total = 0; foreach (Product prod in products.Filter(categoryFilter)) { total += prod.Price; } return View("Result", (object)String.Format("Total: {0}", total)); } } }
Listing 4-21. Using a Lambda Expression to Replace a Delegate Definition
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } // Other action methods omitted for brevity public ViewResult UseFilterExtensionMethod() { IEnumerable<Product> products = new ShoppingCart { Products = new List<Product> { new Product{Name = "Kayak", Category = "Watersports", Price = 275M}, new Product{Name = "Lifejacket", Category = "Watersports", Price = 48.95M}, new Product{Name = "Soccer ball", Category = "Soccer", Price = 19.50M}, new Product{Name = "Corner flag", Category = "Soccer", Price = 34.95M} } }; Func<Product, bool> categoryFilter = prod => prod.Category == "Soccer"; decimal total = 0; foreach (Product prod in products.Filter(categoryFilter)) { total += prod.Price; } return View("Result", (object)String.Format("Total: {0}", total)); } } }
Listing 4-22. A Lambda Expression Without a Func
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } // Other action methods omitted for brevity public ViewResult UseFilterExtensionMethod() { IEnumerable<Product> products = new ShoppingCart { Products = new List<Product> { new Product{Name = "Kayak", Category = "Watersports", Price = 275M}, new Product{Name = "Lifejacket", Category = "Watersports", Price = 48.95M}, new Product{Name = "Soccer ball", Category = "Soccer", Price = 19.50M}, new Product{Name = "Corner flag", Category = "Soccer", Price = 34.95M} } }; decimal total = 0; foreach (Product prod in products.Filter(prod => prod.Category == "Soccer")) { total += prod.Price; } return View("Result", (object)String.Format("Total: {0}", total)); } } }
Listing 4-23. Extending the Filtering Expressed by the Lambda Expression
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LanguageFeatures.Models; namespace LanguageFeatures.Controllers { public class HomeController : Controller { public string Index() { return "Navigate to a URL to show an example"; } // Other action methods omitted for brevity public ViewResult UseFilterExtensionMethod() { IEnumerable<Product> products = new ShoppingCart { Products = new List<Product> { new Product{Name = "Kayak", Category = "Watersports", Price = 275M}, new Product{Name = "Lifejacket", Category = "Watersports", Price = 48.95M}, new Product{Name = "Soccer ball", Category = "Soccer", Price = 19.50M}, new Product{Name = "Corner flag", Category = "Soccer", Price = 34.95M} } }; decimal total = 0; foreach (Product prod in products.Filter( prod => prod.Category == "Soccer" || prod.Price > 20)) { total += prod.Price; } return View("Result", (object)String.Format("Total: {0}", total)); } } }