Get list of property value from another list based on supplied property name using indexer in c#

Recently in one of our MVC application, I have had a requirement to read property value from one generic list by using property name, i.e. For exa. Consider one function named – GetPropertyValueList() which has one parameter named – propertyName. By using that parameter this function return the List<object> (List of property value).

OK, Let me explain further my requirement in detail. One of our end user wanted to migrate some of his customers manually. So I had to develop one page which displays specific customer list retrieve from the database. Now this page contains different sections to display list of property value. For exa. “LastName” property section displays only list of customer’s last name in radio-button list. Same way in other section let say “Age” property section displays only list of customer’s age in radio-button list. Same way for other properties too of customer class.

Now let’s see this practically. To achieve this functionality I need to develop several modal classes in my application’s modal layer. For demo purpose I have shown you these things in action in one console application in this post.

My first modal class is a normal “Customer” class.

public class Customer
{

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Age { get; set; }

    public string MobileNo { get; set; }

    // Same way there are more than 20 properties in my mvc application
    //public string Address { get; set; }
}

My second modal class is “SourceCustomerInfo” class.

public class SourceCustomerInfo
{
	///<summary>
	/// To get the name of property at run time of Customer class
	/// </summary>

	public Customer customerField { get; set; }

	///<summary>
	/// Contain list of customers from database to migrate
	/// </summary>

	public List<Customer> customerList { get; set; }

}

 

In SourceCustomerInfo class first property customerField is used to get list of property value from customerList property. You can see the detail usage of this class in our console application.

My third modal class is “CustomerFieldValueList” class.

public class CustomerFieldValueList
{
	///<summary>
	/// Contain name of the property to render in the lable
	/// </summary>

	public string FieldName { get; set; }

	///<summary>
	/// Contain list of property value to render in the radio-button list
	/// </summary>

	public List<object> FieldValueList { get; set; }

}

Why I need to develop this modal ? Well, my MVC View renders all labels and its related radio-button list dynamically (By using above modal class). In the above class first property FieldName is used as label in MVC View and second property FieldValueList is used to fill radio-button list. Hmmm sorry for my bad English, But Here is the screen-shot of this class of what you’ll get at run time in each property for better understanding.

FieldValueList

All right, now the key point is here. To achieve my key requirement I need to use “Indexers” – a very special type of class member in C#. An indexer allows an object to be indexed like an array. The main use of “indexers” is to support the creation of specialized arrays or list. For more information on “Indexers” refer this MSDN link.

Here is the indexer that I have added in “Customer” class.

public class Customer
{

	///<summary>
	/// Get the value by supplied property name
	/// </summary>
	/// <param name="propertyName"></param>
	/// <returns></returns>
	public object this[string propertyName]
	{
		get
		{
			return this.GetType().GetProperty(propertyName).GetValue(this, null);
		}
	}

	public string FirstName { get; set; }

	public string LastName { get; set; }

	public int Age { get; set; }

	public string MobileNo { get; set; }

	// Same way there are more than 20 properties in my mvc application
	//public string Address { get; set; }

}

As you can see that I have read property value by using propertyName as parameter thru reflection in indexer.
Let’s combine all of these modal classes in one console application and see it in action. Here i have show you only the Main() method code. You can download the full source code from here.

static void Main(string[] args)
{
	var sourceCustomerInfo = new SourceCustomerInfo() {customerField = new Customer() };

	// Get the name of all property of customer class using reflection in array.
	var arrayPropNames = sourceCustomerInfo.customerField
							.GetType()
							.GetProperties()
							.Select(p => p.Name)
							.ToArray();
	// Fill the Customer list
	sourceCustomerInfo.customerList = new List<Customer>
	{
		new Customer() { FirstName="Kapil", LastName="Dev", Age=55, MobileNo="123" },
		new Customer() { FirstName="Sachin", LastName="Tendulkar", Age=45, MobileNo="123" },
		new Customer() { FirstName="Rahul", LastName="Dravid", Age=50, MobileNo="123" }
	};

	var fieldValueList = new List<CustomerFieldValueList>();
	//Now we iterate thru each property name that we already get in array
	foreach (var propertyName in arrayPropNames)
	{
		// Check propertyName is not blank or not our indexers
		if (!string.IsNullOrEmpty(propertyName) && propertyName != "Item")
		{
			// Initialize new instance of CustomerFieldValueList class
			var customerFieldValueList = new CustomerFieldValueList();

			// Set customerField with current property name
			customerFieldValueList.FieldName = propertyName;

			// Get the list of property value by supplied propertyName parameter using indexers
			// from the customerList property of SourceCustomerInfo class.
			customerFieldValueList.FieldValueList = sourceCustomerInfo.customerList.Select(p => p[propertyName]).ToList();

			// Now add this class instance into fieldValueList List.
			fieldValueList.Add(customerFieldValueList);
		}
	}

	// Now we are ready to render it in our MVC View.
	// Here we'll render it in console.
	fieldValueList.ForEach(obj =>
		{
			// Display FieldName value after 15 spaces
                        Console.WriteLine("FieldName  => {0, 15}", obj.FieldName);

			obj.FieldValueList.ForEach(lst =>
				{
					// Display property value after 15 spaces
					Console.WriteLine("     List  => {0, 15}", lst);
				});
			Console.WriteLine("=========================================");
		});

	Console.ReadLine();
}

And here is the output in console.

FinalResult

That’s it folks. Hope you like this post. Leave your comments.

Advertisements

The Role of data type precedence for COALESCE and ISNULL Function in SQL Server

Few days ago, I had a discussion regarding key difference between COALESCE and ISNULL function with one of my colleague in my office. Though he knows some of the differences but he doesn’t have any idea about data type precedence in both of these functions. How the data type of the result is determine here. So i thought to write the post regarding that.

In COALESCE data type of the result determines based on the data type precedence. As per the MSDN

Returns the data type of expression with the highest data type precedence.

 Let’s see it practically.

SELECT COALESCE (NULL, 1, GETDATE());

As this function evaluates the arguments in order and returns the first non-nullable value. In the above query first argument is null, so it evaluates second argument which is “1” and is of “Int” data type. But the third argument is “GetDate()” which is of “Datetime” data type and DATETIME data type has a higher precedence than INT. So the output of the above query is in DATETIME i.e. When we execute that query SQL Server will convert “1” into DATETIME.

1900-01-02 00:00:00.000

coalesce_exa1

Let’s see the another query.

SELECT COALESCE (NULL, 'Hello World', 1);

 coalesce_exa2

As you can see in above query that SQL Server will try to convert “Hello World” which is of VARCHAR data type into INT and results in error. Why ? because “INT” has highest data type precedence than “VARCHAR”. You can refer the Data Type Precedence chart from MSDN.

In ISNULL data type of the result determines based on the “first argument”, i.e data type precedence will not influenced the result. As per the MSDN

Returns the same type as check_expression. If a literal NULL is provided as check_expression, returns the datatype of the replacement_value.

 NOTE: Here check_expression is the first argument and replacement_value is the second argument passed in the ISNULL  function.

Now Let’s see it practically.

DECLARE @var_datetime DATETIME

SELECT ISNULL(@var_datetime, 1)

isnull_exa1

Here variable “@var_datetime” is of type datetime and by default it’s value is NULL. So as the first argument is of type DATETIME which means result type is of datetime. So when you execute query, sql server will convert “1” into datetime and return the result.

Let’s see the another query.

DECLARE @var_int INT

SELECT ISNULL(@var_int, 'Hello World')

isnull_exa2

As you can see that first argument is of type INT. So SQL Server will try to convert “Hello World” which is of VARCHAR into INT and results in error.

That’s it for now. Hope you like this post.