C# Essential Language Features Part 1
We are
going to start looking into some basic and advanced C# Language features in
this article. I will be covering some features which are good to know as
general and while implementing the MVC application.
Object
and Collection Intializers
Creating
Object and then assigning values to the properties is every time task for the
developer. Some time the object is consist of many properties/fields for which
we need to assign some values as shown in Listing 1
Listing
1.
class
Program
{
static void Main(string[]
args)
{
//Create
a new Shopping Cart object
ShoppingCart
cart = new ShoppingCart();
// Create
a new Product Object
Product
prod = new Product();
//Set the
property value of Product
prod.Name = "Dell XPS";
prod.Category="PC";
prod.Description="Laptop from Dell";
prod.ProductID=01;
prod.Price=550;
//Set the
properties
List<Product> lstProd = new List<Product>();
lstProd.Add(prod);
cart.Products = lstProd;
Console.WriteLine(cart.Products.Count);
foreach
(Product prods in
cart.Products)
{
Console.WriteLine("Product Name {0}, Price {1} , Category {2}",
prods.Name, prods.Price, prods.Category);
}
Console.Read();
}
In above
Sample ShoppingCart class holds the
property which holds the List of Product. Now assigning the product to shopping
card we have to assign the List to Shopping card. The above sample assign only
one Product, now if you want to assign many product you have create different
object of Product and add to the List of Product type which will be little
cumbersome.
Now if we Initialize those values while creating the Object will help to reduce the
complexity of assigning as shown in Listing 2.
Listing 2.
static
void Main(string[]
args)
{
ShoppingCart
cart = new ShoppingCart
{
Products = new List<Product> {
new
Product {Name = "Dell
XPS", Category = "Laptop",
Price = 275M},
new
Product {Name = "HP",
Category = "Desktop", Price =
48.95M},
new
Product {Name = "ThinkPad",
Category = "Laptop", Price =
19.50M},
new
Product {Name = "Acer",
Category = "Desktop", Price =
34.95M}
}
};
Console.WriteLine("Total Items in Cart is " +
cart.Products.Count);
foreach
(Product prods in
cart.Products)
{
Console.WriteLine("Product Name {0}, Price {1} , Category {2}",
prods.Name, prods.Price, prods.Category);
}
Console.Read();
}
Extension
Methods
First
thing will come in mind what is Extension Methods? Extension Methods are a convenient way of adding the methods to the class which you don’t own and you
don’t have source code to modify those classes.
As
mentioned above in Listing 1 about
the ShoppingCart Class which holds the collection of Products
using
System.Collections.Generic;
public
class ShoppingCart
{
public List<Product>
Products { get; set;
}
}
Now assume
this class is coming from Third party and we don’t have source code to modify
this class. Now I want to add a method to this class to get the Total Value (Price) of the product
Objects in the ShoppingCart. In this scenario the Extension Method is handy to
implement that functionality as shown in Listing
3
Listing
3.
public
static class ShoppingExtension
{
public
static decimal
TotalPrices(this
ShoppingCart cartParam)
{
decimal
total = 0;
foreach
(Product prod in
cartParam.Products)
{
total += prod.Price;
}
return
total;
}
The this Keyword in front of the first parameter makes the TotalPrices as
an extension mentioned for ShoppingCart
Applying
an Extension Method
Calling Extension
method TotalPrices() is shown in below
Listing
static
void Main(string[]
args)
{
ShoppingCart
cart = new ShoppingCart
{
Products
= new List<Product> {
new Product {Name
= "Dell XPS", Category = "Laptop", Price = 275M},
new
Product {Name = "HP",
Category = "Desktop", Price =
48.95M},
new
Product {Name = "ThinkPad",
Category = "Laptop", Price =
19.50M},
new
Product {Name = "Acer",
Category = "Desktop", Price =
34.95M}
}
};
Console.WriteLine("Total Prices is " + cart.TotalPrices());
Console.Read();
}
Extension
Method to An Interface
We can also add the Extension Method
to an interface, which allow us to call the extension mentioned on all of the
classes which implements that interface. Listing
4 shows the ShoppingCart class is implementing IEnumerable<Product>
Interface
Listing 4
public
class ShoppingCart
: IEnumerable<Product>
{
public List<Product>
Products { get; set;
}
public IEnumerator<Product>
GetEnumerator()
{
return
Products.GetEnumerator();
}
IEnumerator
IEnumerable.GetEnumerator()
{
return
GetEnumerator();
}
}
Let’s update the
extension method as shown in Listing 3 as
below
public
static decimal
TotalPrices(this IEnumerable<Product> cartParam)
{
decimal
total = 0;
foreach
(Product prod in
cartParam)
{
total
+= prod.Price;
}
return
total;
}
Now let’s call
this extension method from main class.
static
void Main(string[]
args)
{
IEnumerable<Product>
cart = new ShoppingCart
{
Products = new List<Product> {
new
Product {Name = "Dell
XPS", Category = "Laptop",
Price = 275M},
new
Product {Name = "HP",
Category = "Desktop", Price =
48.95M},
new
Product {Name = "ThinkPad",
Category = "Laptop", Price =
19.50M},
new
Product {Name = "Acer",
Category = "Desktop", Price =
34.95M}
}
};
Console.WriteLine("Total Items in Cart is " +
cart.TotalPrices());
Console.Read();
}
In above example
you will notice that Shopping Cart is type of IEnumerable<Product> so assigning the object to IEnumerable<Product>.
Calling of
TotalPrices will be same but now it can be applied to any Class which
implements the Interface IEnumerable<Product>
Creating Extension Methods for Filtering
This is last
thing I will be showing in part 1 of series. So now you get some hands on the
extension method how to create and apply. Now I will show you how to add on to
the extension method which will help you to filter the data.
An extension
method that operates on an IEnumerable and that also returns an IEnumerable
can use the yield keyword to apply selection criteria to items in the
source data to produce a reduced set of results.
Will Create the
Two Different types of Filters in Listing
5
Listing 5
public static class ShoppingExtension
{
public static decimal TotalPrices(this
IEnumerable<Product>
cartParam)
{
decimal total = 0;
foreach (Product
prod in cartParam)
{
total += prod.Price;
}
return total;
}
public static IEnumerable<Product>
FilterByCategory(this IEnumerable<Product> productEnum, string
categoryParm)
{
foreach (Product
prod in productEnum)
{
if(prod.Category.Equals(categoryParm)){
yield return
prod;
}
}
}
public static IEnumerable<Product>
Filter(this IEnumerable<Product> productEnum, Func<Product,bool>
param)
{
foreach (Product
prod in productEnum)
{
if
(param(prod))
{
yield return
prod;
}
}
}
}
As shown above
you will see two Filters, one is FilterByCategory which is specific to the
Category filed. So when you pass any value it will compare with Category
property and return the collection of matching data.
Second method is
more generic where we will be using Delegate. Where it will work on any
Property of Product Class as the delegate is to use Product Class.
Below is the implementation how to use those filters,
static void Main(string[] args)
{
IEnumerable<Product>
card = new ShoppingCart
{
Products = new
List<Product>
{
new Product {Name
= "Dell XPS", Category = "Laptop", Price = 275M},
new Product {Name
= "HP", Category = "Desktop", Price = 48.95M},
new Product {Name
= "ThinkPad", Category = "Laptop", Price = 19.50M},
new Product {Name
= "Acer", Category = "Desktop", Price = 34.95M}
}
};
decimal result = card.TotalPrices();
Console.WriteLine("Total
from List {0}", result);
Console.WriteLine("Using Extension Method");
IEnumerable<Product> iProd = card.FilterByCategory("Desktop");
foreach (Product
prod in iProd)
{
Console.WriteLine("Name: {0}, Price {1:c}", prod.Name,
prod.Price);
}
Console.WriteLine("Using
Delegate");
IEnumerable<Product> eProd = card.Filter(prod => prod.Category.Equals("Laptop"));
foreach (Product
prod in eProd)
{
Console.WriteLine("Name:
{0}, Price {1:c}", prod.Name, prod.Price);
}
}
No comments:
Post a Comment