Preserving stacktrace information when processing exceptions with C# .NET

Have you ever tried to hunt down a bug and been blocked by an incomplete stacktrace? The stacktrace might point to a place in your code where you threw the exception with the “throw” keyword but there’s no information on where the exception was originally thrown.

This can happen if you process the exception within the catch clause, e.g. log it somewhere and then throw it back to the call stack.

Consider the following simple code where the first method calls the second which calls the next etc. and the last one throws an exception. The first method catches the exception, prints it to the Debug window and throws it:

Read more of this post

Finding the user’s current region using RegionInfo in .NET C#

The CultureInfo object helps a lot in finding information about the user’s current culture. However, on occasion it may not be enough and you need to find out more about that user’s regional characteristics. You can easily retrieve a RegionInfo object from CultureInfo which will hold information about a particular country or region.

You can find the current region in two ways from CultureInfo:

CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
// or 
regionInfo = new RegionInfo(cultureInfo.Name);

string englishName = regionInfo.EnglishName;
string currencySymbol = regionInfo.CurrencySymbol;
string currencyEnglishName = regionInfo.CurrencyEnglishName;
string currencyLocalName = regionInfo.CurrencyNativeName;

My computer is set to use Swedish-Sweden as the specific culture so I get the following values from top to bottom:

  • Sweden
  • kr
  • Swedish krona
  • Svensk krona

If I change the current culture to my home country, i.e. Hungary…

CultureInfo hungaryCulture = new CultureInfo("hu-HU");
Thread.CurrentThread.CurrentCulture = hungaryCulture;
regionInfo = new RegionInfo(hungaryCulture.LCID);
englishName = regionInfo.EnglishName;
currencySymbol = regionInfo.CurrencySymbol;
currencyEnglishName = regionInfo.CurrencyEnglishName;
currencyLocalName = regionInfo.CurrencyNativeName;

…then the values are of course adjusted accordingly:

  • Hungary
  • Ft
  • Hungarian Forint
  • forint

Read all posts related to Globalisation in .NET here.

Using DateTimeFormatInfo to localise date and time in .NET C#

Every programmer loves working with dates and time, right? Whether or not you like it it is inevitable to show the dates in a format that the viewer understands. You should not show dates presented according to the US format in Japan and vice versa.

The DateTimeFormatInfo class includes a range of useful properties to localise date and time. The entry point to the DateTimeFormatInfo class is CultureInfo. E.g. if you’d like to format a date according to various cultures – Swedish, Hungarian and German – then you can do it as follows:

CultureInfo swedishCulture = new CultureInfo("sv-SE");
DateTimeFormatInfo swedishDateFormat = swedishCulture.DateTimeFormat;

CultureInfo hungarianCulture = new CultureInfo("hu-HU");
DateTimeFormatInfo hungarianDateFormat = hungarianCulture.DateTimeFormat;

CultureInfo germanCulture = new CultureInfo("de-DE");
DateTimeFormatInfo germanDateFormat = germanCulture.DateTimeFormat;
			
DateTime utcNow = DateTime.UtcNow;

string formattedDateSweden = utcNow.ToString(swedishDateFormat.FullDateTimePattern);
string formattedDateHungary = utcNow.ToString(hungarianDateFormat.FullDateTimePattern);
string formattedDateGermany = utcNow.ToString(germanDateFormat.FullDateTimePattern);

…which yields the following formatted dates:

  • den 12 juni 2014 20:08:30
  • 2014. június 12. 20:08:30
  • Donnerstag, 12. Juni 2014 20:08:30

DateTimeFormatInfo includes patterns for other types of date representations, such as MonthDayPattern, LongDatePattern etc.

You can also get the names of the days and months:

string[] swedishDays = swedishDateFormat.DayNames;
string[] germanDays = germanDateFormat.DayNames;
string[] hungarianDays = hungarianDateFormat.DayNames;

string[] swedishMonths = swedishDateFormat.MonthNames;
string[] hungarianMonths = hungarianDateFormat.MonthNames;
string[] germanMonths = germanDateFormat.MonthNames;

You can do a lot more with DateTimeFormatInfo:

  • The Calendar associated with the culture
  • The date separator
  • Abbreviated month and day names
  • First day of the week

…and more. I encourage you to inspect the available properties of the DateTimeFormatInfo object with IntelliSense in Visual Studio.

Read all posts related to Globalisation in .NET here.

Comparing strings using the CompareInfo class in .NET C#

It’s important to be aware of the cultural settings in a globalised application when comparing strings. The CompareInfo class and the CompareOptions enumeration provide a useful way to compare strings based on specific cultures.

One way to get hold of the CompareInfo class belonging to a specific culture is through the CultureInfo class:

CultureInfo swedishCulture = new CultureInfo("sv-SE");
CompareInfo swedishCompareInfo = swedishCulture.CompareInfo;

CultureInfo hungarianCulture = new CultureInfo("hu-HU");
CompareInfo hungarianCompareInfo = hungarianCulture.CompareInfo;

CultureInfo germanCulture = new CultureInfo("de-DE");
CompareInfo germanCompareInfo = germanCulture.CompareInfo;

The CompareInfo object has a Compare method which returns 0 if the strings are equal, -1 if the first string is less than the second and 1 if the opposite is the case. The following comparison of two German strings returns -1 as by default the comparison is case-sensitive:

int comparison = germanCompareInfo.Compare("mädchen", "Mädchen");

This is where the CompareOptions enumeration proves useful. Here are the possible values:

  • IgnoreCase: make the comparison case-insensitive
  • IgnoreNonSpace: ignore diacritics, or officially non-spacing combining characters in Unicode. Example: “Madchen” will be equal to “Mädchen” with this flag
  • IgnoreSymbols: ignore symbols, like white-space, #, $, % etc. “Mädch$en” and “M#ädchen” will be considered equal with this flag
  • IgnoreKana and IgnoreWidth: concern mostly the Japanese language
  • None: the default value if the basic overload of Compare is called
  • Ordinal: quick but culture-insensitive comparison based on the Unicode value of each character
  • OrdinalIgnoreCase: same as Ordinal but the comparison is also case-insensitive
  • StringSort: use a sort algorithm where non-alphanumeric symbols, such as ‘-‘ come before the alphanumeric characters

Read all posts related to Globalisation in .NET here.

Finding the current culture settings using the CultureInfo class in .NET C#

Finding the the culture settings – the locale – of a thread is straightforward in .NET:

CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;

We extract the current culture from the current thread. The CultureInfo class holds a number of properties to extract information from it. Examples:

string cultureName = cultureInfo.Name;
string cultureDisplayName = cultureInfo.DisplayName;
string nativeName = cultureInfo.NativeName;
string englishName = cultureInfo.EnglishName;
string cultureAbbreviation = cultureInfo.TwoLetterISOLanguageName;

As my computer is set to run with Swedish settings I got the following values from top to bottom:

  • sv-SE
  • Swedish (Sweden)
  • svenska (Sverige)
  • Swedish (Sweden)
  • sv

Cultures are represented by the following format:

  • Neutral culture, “sv” in the above case, is the ISO language name which is tied to the language
  • Specific culture, “SE” in the above case, denotes the geographical location of the culture
  • The two elements are connected with a hyphen “-“, i.e. “sv-SE” in the above example

Specific culture is the most precise description of the user’s locale. It not only designates the language but the region as well. E.g. Swedish is spoken in Finland as well so the neutral culture “sv” is not enough to locate the user. There’s a specific “sv-FI” format for that. This aspect becomes a lot more important with broadly used languages such as French or English. French spoken in France is different from French spoken in Canada. Therefore we need to use fr-FR and fr-CA for the purpose of formatting and proper localisation.

Besides neutral and specific cultures there’s a third type of culture called invariant culture. This is not tied to any specific culture but is closest to English. It may be tempting to use this culture for other purposes such as date and time comparisons but you’ll most likely get false results in a globalised, culture aware application.

The current culture is used for formatting purposes behind the scenes:

decimal price = 10.43M;
string formattedDecimalDefault = price.ToString("C");

I got “10,43 kr” where ‘kr’ denotes the currency in Sweden, i.e. Swedish krona.

You can also set the current culture of the thread:

CultureInfo usCulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = usCulture;
string formattedPriceUs = price.ToString("C");

This immediately yields “$10.43”.

The invariant culture is denoted by an empty string:

CultureInfo invariantCulture = new CultureInfo("");
Thread.CurrentThread.CurrentCulture = invariantCulture;
string formattedPriceUs = price.ToString("C");

Neutral cultures are denoted by the ISO language names, e.g.:

CultureInfo englishCulture = new CultureInfo("en");
Thread.CurrentThread.CurrentCulture = englishCulture;
string formattedPriceUs = price.ToString("C");

Which will format the price according to the en-US specific culture.

As you typed “Thread.CurrentThread.” in the editor you may have noticed the CurrentUICulture property. That also returns a CultureInfo object. As the name suggests, it denotes the culture used to show prices, dates, time etc. in the application UI. CurrentCulture and CurrentUICulture will most often be the same, but be aware that they can be different. You might perform calculations in a culture but show the results in another one. Also, you can always manipulate the CurrentCulture of the thread during an application’s lifetime. However, you can only set the current UI culture at the application’s start up.

Read all posts related to Globalisation in .NET here.

Extension methods in .NET part 3: mixture of useful methods

Introduction

So far in this series we’ve looked at the foundations of extension methods in C#. We’ve also seen a number of examples and special cases. We’ll continue our discussion of with a mixture of useful applications of extension methods.

Exceptions

Extending exceptions can be useful if you’d like to get a user-friendly output of wrapped exceptions. You normally don’t want to show the full stacktrace of the top-level and wrapped exceptions to a user. The following extension method collects the exception message from the inner exceptions as long as they are not null:

public static string UserFriendlyFullMessage(this Exception exception)
{
	StringBuilder exceptionBuilder = new StringBuilder();
	while (exception != null)
	{
		exceptionBuilder.AppendLine(exception.Message);
		exception = exception.InnerException;
	}
	return exceptionBuilder.ToString();
}

Let’s say you have the following method:

private static void TestExceptionExtension(int divideBy)
{
	try
	{
		int res = 10 / divideBy;
	}
	catch (Exception ex)
	{
		InvalidOperationException ioex = new InvalidOperationException("What are you doing???", ex);
		string errorMessage = string.Concat("Division failed. Tried to divide by ", divideBy);
		throw new ApplicationException(errorMessage, ioex);
	}
}

Call the method as follows and print the exception messages on the console window:

try
{
	TestExceptionExtension(0);
}
catch (Exception ex)
{
	String messages = ex.UserFriendlyFullMessage();
	Console.WriteLine(messages);
}

The output is:

Division failed. Tried to divide by 0
What are you doing???
Attempted to divide by zero.

This is a cleaner presentation of the exceptions to a user who is not familiar with stacktraces and should not even be able to view them.

Enumerations

Consider the following enumeration:

public enum Difficulty
{
	Easy
	, Medium
	, Hard
	, Master
}

We can extend enumerations the same way as other objects. The following extension method will hide the ugly Enum.GetName call behind a friendly method signature:

public static class EnumExtensions
{
	public static string ToUserFriendlyString(this Enum value)
	{
		return Enum.GetName(value.GetType(), value);
	}
}

You can call this extension method on any enumeration:

string val = Difficulty.Easy.ToUserFriendlyString();

You can add an extended description to a specific enum value as follows:

public enum Difficulty
{
	[Description("This is the easy level")]
	Easy
	, Medium
	, Hard
	, Master
}

…where the Description attribute is found in the System.ComponentModel namespace so you’ll need to reference the correct library.

You can read the detailed description using Reflection. We’ll hide the ugly details behind another extension method:

public static string GetDetailedDescription(this Enum value)
{
	FieldInfo fieldInfo = value.GetType().GetField(value.ToUserFriendlyString());
	DescriptionAttribute descriptionAttribute = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute;
	return descriptionAttribute == null ? value.ToUserFriendlyString() : descriptionAttribute.Description;
}

We check if there’s a Description attribute on the enumeration value. If that’s the case then we return the description. Otherwise we’ll use the extension method defined above to return the default value.

You can call these methods as follows:

string val = Difficulty.Easy.ToUserFriendlyString();
string desc = Difficulty.Easy.GetDetailedDescription();

Web API

If Web API doesn’t tell you much then check out its home page. It is a great technology to create RESTful web services. According to RFC 2616, i.e. the HTTP protocol specifications, if a new resource is created with a POST or PUT request then the service should respond with a 201 status code – meaning Created – and a Location header specifying the URL of the newly created resource. Example: “Location: http://api.mysite.com/products/10”.

It’s customary for Web API controllers to return a HttpResponseMessage object to the client. It can respond with other objects, such as a string, but the HttpResponseMessage object is very rich. You can set the status code, the content body, the HTTP response headers etc.

The solution will therefore extend the HttpResponseMessage object. It will also accept an HttpRequestMessage object which includes the details about the original incoming request. The request is necessary so that we can find the original URI that was used for the POST/PUT operation. We’ll follow the convention that individual resources can be located by an ID parameter in the URL like in the example above: /products/10.

For the solution to work the Controller that processes the POST/PUT request must also be able to process the GET. This is so that URL in the POST/PUT request can be used to extract the URL for the GET in the Location header. Also, the Controller must have a GET method that returns a resource by its id. The following extension method will do the job:

public static void InsertLocationHeader(this HttpResponseMessage httpResponseMessage, 
			HttpRequestMessage httpRequestMessage, int idOfNewResource)
{
	string uri = string.Concat(httpRequestMessage.RequestUri, "/", idOfNewResource);
	httpResponseMessage.Headers.Location = new Uri(uri);
}

We don’t need to return anything from this method. We just take advantage of the fact that objects are reference types and therefore we can modify the state of the httpResponseMessage object we’re extending.

The method can be called as follows:

HttpResponseMessage httpResp = //build the response message;
httpResp.InsertLocationHeader(Request, 20);

The original request can be acquired using the built-in Request property.

Epoch datetime

There’s no built in method in .NET to convert DateTime objects to UNIX timestamps, i.e. to the seconds passed since the midnight of Jan 01 1970. Nothing could be simpler with an extension method:

public static long ToUnixTimeStamp(this DateTime dateTimeUtc)
{
      DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
      TimeSpan timeSpan = dateTimeUtc - epoch;
      return Convert.ToInt64(timeSpan.TotalSeconds);
}

We construct a DateTime with the starting point for the Unix timestamp. We get the time span between ‘now’ and the start date. Finally we extract the seconds passed during that time span.

SecureString

The SecureString object can be used to keep confidential text securely in memory. The following extension method will convert a string to a SecureString:

public static SecureString ToSecureString(this string s)
{
        if (s == null)
             return null;

        SecureString psw = new SecureString();
        foreach (char c in s.ToCharArray())
        {
            psw.AppendChar(c);
        }
        return psw;
}

Various

The list of useful extension methods could go on and on. By now you’ve probably got the general idea behind extension methods so you can construct your own. To finish off this short series here’s a couple more methods that you can use in your projects.

Check if integer is within some interval:

public static bool IsBetween(this int theNumber, int lower, int higher)
{
	return (theNumber >= lower) && (theNumber <= higher);
}

Remove some prefix or suffix from a string:

public static string TrimPrefix(this string str, string prefix)
{
        if (!String.IsNullOrEmpty(str) && !String.IsNullOrEmpty(prefix) && str.StartsWith(prefix))
	{
		 return str.Substring(prefix.Length);
	}
	return str;
}

public static string TrimSuffix(this string str, string suffix)
{
        if (!String.IsNullOrEmpty(str) && !String.IsNullOrEmpty(suffix) && str.EndsWith(suffix))
	{
		 return str.Remove(str.Length - suffix.Length);
	}
	return str;
}

Extract the base64 encoded username and password from the Basic Auth header of a HttpRequestMessage object in Web API:

public static Tuple<string, string>
            ExtractUsernameAndPasswordFromHttpHeader(this HttpRequestMessage requestMessage)
{
            Dictionary<string, string> headers = requestMessage.ReadHeaders();
            if (headers.ContainsKey("Authorization"))
            {
                string authHeaderValue = headers["Authorization"];
                authHeaderValue = authHeaderValue.Trim();
                string encodedCredentials = authHeaderValue.Substring(6);
                byte[] decodedBytes = Convert.FromBase64String(encodedCredentials);
                string s = new ASCIIEncoding().GetString(decodedBytes);
                string[] userPass = s.Split(new char[] { ':' });
                string username = userPass[0];
                string password = userPass[1];
                return new Tuple<string, string>(username, password);
            }
            else
            {
                throw new ArgumentNullException("Username and password couldn't be extracted from the HttpHeaders collection.");
            }
}

Extract all headers from a HttpRequestMessage into a Dictionary:

public static Dictionary<string, string>
            ReadHeaders(this HttpRequestMessage requestMessage)
{
      return ExtractHeaders(requestMessage.Headers);
}

private static Dictionary<string, string> ExtractHeaders(HttpHeaders headers)
{
            Dictionary<string, string> dict = new Dictionary<string, string>();
            foreach (var kvp in headers.ToList())
            {
                if (kvp.Value != null)
                {
                    string header = string.Empty;
                    foreach (var j in kvp.Value)
                    {
                        header += j + " ";
                    }
                    dict.Add(kvp.Key, header);
                }
            }
            return dict;
}

Check if an IEnumerable of T is empty:

public static bool IsEmpty<T>(this IEnumerable<T> list)
{
	if (list == null)
		return true;

	if (list is ICollection<T>) 
        	return ((ICollection<T>)list).Count == 0;
	else
		return !list.Any();
}

Extension methods in C# .NET part 2: arrays, collections, portability

Introduction

We’ll continue our discussion of extension methods by looking at arrays, collections and other types. We’ll also discuss portability issues.

You can find the previous part in this series here.

Arrays and collections

Open up the demo project we’ve been working on in this series. Locate the ExtensionSamples project and add a new folder called Collections. We’ll reuse much of the code we added to the Interfaces folder. Here we want to introduce another search functionality similar to the SearchProduct extension which searched through one specific data source. We now want to search through all data sources in one call. Add a class called ProductCollectionExtensions to the Collections folder and make it public and static. Make sure that the namespace is the same as for the IProductDataSource interface to avoid having to copy namespaces. Add the following extension method stub:

public static IEnumerable<Product> GetAllItemsByName(this IProductDataSource[] productDataDources, string searchTerm)
{
	return null;
}

You can see that we’re extending an array of product data sources. We want to search through all data sources and find a product with some name in all those sources.

A method call from Main looks like this:

private static void TestCollectionExtensions()
{
	IProductDataSource[] dataSources = new IProductDataSource[] { new DatabaseSource(), new FileSource(), new ApiSource() };
	string searchTerm = "f";

	IEnumerable<Product> productsWithId = dataSources.GetAllItemsByName(searchTerm);
}

In the method implementation we can reuse the already existing SearchProduct extension on each data source in an iteration:

public static IEnumerable<Product> GetAllItemsByName(this IProductDataSource[] productDataDources, string searchTerm)
{
	List<Product> products = new List<Product>();
	foreach (IProductDataSource productDataSource in productDataDources)
	{
		products.AddRange(productDataSource.SearchProduct(searchTerm));
	}
	return products;
}

Yet again we extended the functionality of IProductDataSource without having to touch the code in the concrete classes.

This was an example of how to write extensions for arrays. The same applies for all types of sequences, such as IEnumerable, List, IList etc. The GetAllItemsByName method can equally be written as follows:

public static IEnumerable<Product> GetAllItemsByName(this IEnumerable<IProductDataSource> productDataDources, string searchTerm)

The code will still compile as an array is also an IEnumerable so the change in the signature doesn’t break the existing code. You can call the GetAllItemsByName on any collection that implements the IEnumerable interface such as a List of T or HashSet of T.

Extending any object

What if you want to make an extension method available on just any type of object? It’s certainly possible. There’s nothing stopping you from declaring the ‘this’ parameter on the built-in type Object. There are scenarios where this is feasible, such as cross-cutting concerns: logging, caching and the like.

Add a new folder in the ExtensionExamples project called Objects. Add a new class to it called ObjectExtensions and declare it public and static. Make sure that the namespace is System. This will ensure that the extension will be available everywhere throughout the solution as System is referenced by default. In general you can restrict the IntelliSense visibility of an extension method by controlling its namespace.

Let’s say we want to be able to get the XML representation of any object for logging purposes. Add the following – admittedly very primitive – implementation to the object extensions class:

public static string ToXmlRepresentation(this object target)
{
	return string.Concat("<xml>", target.ToString(), "</xml>");
}

An exact implementation is beside the point here. The extension method can be called from Main like this:

private static void TestObjectExtensions()
{
	Product p = new Product() { Id = 1, Name = "product" };
	int i = 5;
	string s = "hello";
        DateTime now = DateTime.UtcNow;
	string xmlProduct = p.ToXmlRepresentation();			
	string integerXml = i.ToXmlRepresentation();
	string stringXml = s.ToXmlRepresentation();
        string dateXml = now.ToXmlRepresentation();
}

The extension method will be available on all elements that derive from the Object class: integer, string, built-in objects, interfaces, your custom objects etc.

Types

We can extend Types as well. Add a new class called TypeExtensions to the Objects folder. Make it public and static and change the namespace to System. Let’s say we need some metadata of any Type in .NET:

public static string GetTypeMetadata(this Type target)
{
	return string.Concat("Assembly: ", target.AssemblyQualifiedName, ", name: ", target.FullName);
}

From Main:

private static void TestTypeExtensions()
{
	Product p = new Product() { Id = 1, Name = "product" };
	int i = 5;
	string s = "hello";
	DateTime now = DateTime.UtcNow;
	string productMetadata = p.GetType().GetTypeMetadata();
	string integerMetadata = i.GetType().GetTypeMetadata();
	string stringMetadata = s.GetType().GetTypeMetadata();
	string dateMetadata = now.GetType().GetTypeMetadata();
}

Limitations

You can achieve a lot with extension methods but not everything. In particular you cannot extend the state or accessibility of an object. As extension methods are defined in a separate public static class only those properties and methods will be available to the extension method that are accessible to the class holding the extension methods. You cannot of course reference private properties of an object you’re trying to extend. This is the normal and expected behaviour, extension methods are no exception to the accessibility rules.

You cannot create new instances of an extension method class as it is static. You cannot add instance level fields or properties to it for the same reason. You can certainly add private static fields to an extension method class and maintain some state in them for the incoming object instance. However, as it is a static field it won’t ever be collected by the garbage collector. It will just keep growing.

If you absolutely need to access a private field of the object you’re extending then Reflection can come to the rescue. Imagine that our Product class has a private field with a default value:

private string _privateField = "default";

We can have an extension method like this:

public static string DoSomethingWithPrivateField(this Product p)
{
	FieldInfo fieldInfo = typeof(Product).GetField("_privateField", BindingFlags.Instance | BindingFlags.NonPublic);
	string privateFieldValue = (string)fieldInfo.GetValue(p);
	return privateFieldValue;
}

This means that Reflection will look for a private instance variable called “_privateField” on a Product object. Then we call GetValue and specify that it should be the incoming “p” where the private field should be found.

Call it from Main:

private static void TestPrivateField()
{
	Product p = new Product();
	string privateField = p.DoSomethingWithPrivateField();
}

There you have it, the extension method will find the value of the private field. However, keep in mind that reflection is “expensive” so don’t overuse it. Also, there’s no guarantee that the name of the private field won’t change in the future and the code may break at any point in the future.

Therefore it’s not recommended to use private static variables to keep track of the state or reflection to read private variables from an object. Use them only if there’s no other solution and use them with special care.

Extension methods can obviously only extend objects that are visible to the containing class, such as other public classes. You cannot extend private classes of course or any other class that’s not visible from another class. This is not surprising: extension methods are very much like normal methods and the same basic accessibility rules apply to them as to any other class.

If you create an extension method with the same name as a method that already exists in the class then the compiler will call the class definition. In other words extension methods have a lower priority than class methods and there’s no way around that rule. All you can do is rename the extension method. This can be confusing at first because you won’t get any compiler error or runtime exception but your extension method will not be called.

If you have two extension methods with the same name that extend related types of objects, such as IEnumerable of String and List of String then the extension method with the most specific match will be called. In that case if I call (List of String).ConvertToSomethingElse() then the List of String extension will be called and not IEnumerable of String if you have the following methods:

ConvertToSomethingElse(this List<String> list);
ConvertToSomethingElse(this IEnumerable<String> list);

The same is true if some object implements an interface:

ConvertToSomethingElse(this int integer);
ConvertToSomethingElse(this IConvertible list);

Integer implements the IConvertible interface. So if we call (some integer).ConvertToSomethingElse then both extension methods could apply. The compiler will select the one that extends the Integer type as it is the closest match. If you cast the integer to IConvertible…:

((IConvertible)input).ConvertToSomethingElse();

…then the IConvertible version will be called.

One more limitation, which is not really a limitation but normal behaviour, is that if you define two extension methods with the same signature in the same namespace but different files then the compiler will complain. It’s because it cannot select the correct one. You get the same compiler error if you define two “normal” methods with the same signature in the same class: the compiler will complain about ambiguous references. Keep this in mind when changing the namespace to something too wide, like “System” as some other programmer working on the same project may do the same and there’s a risk of declaring the same signatures leading to a compiler error.

Keep in mind that extension methods are really just syntactic sugar added to .NET. They add functionality to the objects they extend without changing the object definition in any way. This explains why we have the above limitations.

Portability

Extension methods are portable to a high degree with some tricks:

  • Visual Basic projects can call extension methods written in C# as long as there’s no .NET profile mismatch
  • Using an extension method written in .NET4.5 C# library cannot be used directly in a project with no full .NET, e.g. a Windows Phone project with a specific runtime. You can only reference an extension method contained in a Portable Class Library project from a Windows 8/Phone app. When you create a Portable Class Library you can select which frameworks to support: WP8, Windows Store apps, Silverlight 5 and .NET4 and above. Creating an extension method in a portable class library follows exactly the same process as we’ve seen so far. Portable libraries can be referenced from non-portable libraries as well.
  • Extension methods written in .NET4.5 cannot be used in assemblies that target a lower .NET version or a limited profile, like the Client profile. In this case not even a portable client library can be used. In that case what you can do is create a separate C# library, retarget it to a lower .NET framework or profile, such as .NET3.5 Client Profile, and add the extension method in the original C# library as a link: Add Existing Item…, navigate to the cs file containing the extension methods. Before clicking Add in the Add Existing Item window click the little downward pointing triangle on the right side of the Add button. You’ll see two options there: Add and Add Link. Select Add Link. This will at least ensure that the same source code is shared between the original C# library and the one targeting a lower .NET version. Keep in mind that .NET3.5 is the earliest framework where you can use extension methods.

Read the last post in this series here.

Extension methods in C# .NET part 1: the basics

Introduction

Extension methods are simply cool. They allow you to extend the functionality of types that you didn’t write and don’t have direct access to. They look like integral parts of any built-in classes in .NET, e.g.:

DateTime.Now.ToMyCustomDate();
string.ToThreeLetterAbbreviation();

You can extend the following types in C#:

  • Classes
  • Structs
  • Interfaces

You can extend public types of 3rd party libraries. You can also extend generic types, such as List of T and IEnumerable of T. You cannot extend sealed classes.

Extension methods are often used to extend the functionality of the code which is out of the developer’s control, like a 3rd party code base. They also come in handy when extending a class without inheritance or composition.

Let’s dive into extension methods then!

The basics: extending system types

Open Visual Studio and insert a new blank solution called ExtensionMethods. Add to this a C# class library called ExtensionMethods.ExtensionSamples. Insert a folder called Basics to the library project. Insert a class called SampleExtensions to this folder. There are a couple of rules around constructing extension methods:

  • The containing class, like SampleExtensions in this case, must be public and static
  • The extension method itself must be static
  • The type you’re extending must be provided as the first argument in the parameter list. It also must be provided with the ‘this’ keyword

So if you want to extend the System.DateTime class with a method that returns a string then you’ll need the following structure:

public static class SampleExtensions
{
	public static string ToCustomFormat(this DateTime dateTime)
	{

	}
}

This will ensure that whenever we use a DateTime object we can call the ToCustomFormat() method on it. Let’s just add some dummy return value to the method:

public static string ToCustomFormat(this DateTime dateTime)
{
	return "This is some custom datetime format.";
}

Let’s see how you can call this method. Add a new Console project called ExtensionCaller to the solution and add a reference to the library project. Add the following code to Main:

string customDateFormat = DateTime.Now.ToCustomFormat();
Console.WriteLine(customDateFormat);
Console.ReadKey();

You’ll notice that the compiler doesn’t like it:

‘System.DateTime’ does not contain a definition for ‘ToCustomFormat’ and no extension method ‘ToCustomFormat’ accepting a first argument of type ‘System.DateTime’ could be found

You need to add a using statement to the namespace where the extension method is located in Program.cs:

using ExtensionMethods.Extensions.Basics;

The code should compile now. Run the code and you’ll see our little string “This is some custom datetime format.” printed on the console windows. Congratulations, you have just added custom functionality to a native .NET type that is clearly out of direct control.

You can also provide “normal” input parameters to extension methods. All parameters after the first ‘this’ will be input parameters. Let’s see how we can extend the built-in String object. Back in SampleExtensions.cs add the following method:

public static string ToEmail(this string fullName, string nickName, int yearOfBirth)
{
	return string.Concat(fullName.ToLower().Replace(" ", "."), yearOfBirth, "@", nickName.ToLower().Replace(" ", string.Empty), ".com");
}

You can use it from Main as follows:

string fullName = "Elvis Presley";
int birthYear = 1935;
string nickName = "King of Rock and Roll";
string email = fullName.ToEmail(nickName, birthYear);
Console.WriteLine(email);

The output should be elvis.presley1935@kingofrockandroll.com. As you start typing “fullName.” IntelliSense will find the extension method and denote it with a little downward pointing arrow. That’s a telling sign of extension methods: you’ll know you’re not using a native, built-in method of the type if you see that arrow. You’ll in addition see “(extension)” in the description provided by IntelliSense. If IntelliSense doesn’t find the method you’re looking for then double check if the correct namespace has been referenced among the using statements. It won’t find the correct namespace for you. In all other aspects extension methods behave just like normal methods do.

As you see extension methods can be located in just any assembly within your solution. They can also reside in any namespace, even namespaces you don’t own, such as System.String which will alleviate the problem mentioned in the previous paragraph, i.e. the need to import the namespace where the extension method is located. Just make sure to reference the correct library and namespace in the consuming classes. Also, the static class encapsulating the extension methods can have any name as it won’t appear in the consuming classes: normally the word “Extensions” is added to the class name for clarity, such as “StringExtensions”, “DateExtensions”, “PriceExtensions”, but it could be MickeyMouse or DonaldDuck as well.

Let’s continue with more examples. Add a new folder called Strings to the ExtensionSamples project. Add a new class called CustomStringExtensions and make it public and static. Change the namespace to simply “System”. Add the following extension method:

public static string ToXmlName(this string name)
{
	return string.Concat("<name>", name, "</name>");
}

In Main start typing the following:

string xmlName = fullName.tox

IntelliSense will find the ToXmlName() method for you because there’s no extra namespace that must be imported. System is already present:

string xmlName = fullName.ToXmlName();

Let’s see how to add an overloaded extension method:

public static string ToXmlName(this string name, string customAttrib)
{
	return string.Concat("<name attrib=", customAttrib, ">", name, "</name>");
}

So in fact it’s not much different from overloading “normal” methods except for the ‘this’ parameter.

In Main:

string xmlName2 = fullName.ToXmlName("singer");

IntelliSense will show both methods but hides the ‘this’ parameter. It will only show the possible input parameters.

Extending interfaces

Add a new folder to the ExtensionSamples project called Interfaces. In this folder add a new class called Product:

public class Product
{
	public int Id { get; set; }
	public string Name { get; set; }
}

Imagine that the products can be retrieved from a variety of repositories which all implement the following interface:

public interface IProductDataSource
{
	IEnumerable<Product> GetProducts();
}

Also, they inherit from separate abstract classes. This shows the scenario that each repository is different enough so that it’s not reasonable to make them inherit from the same abstract base class:

public abstract class FileSourceBase
{
	public string FileName
	{
		get
		{
			return "source.xml";
		}
	}
}

public abstract class DatabaseSourceBase
{
	public long Size
	{
		get
		{
			return 1000;
		}
	}
}

public abstract class ApiSourceBase
{
	public string Username
	{
		get
		{
			return "apiuser";
		}
	}
}

Add the following implementations:

public class ApiSourcepublic : ApiSourceBase, IProductDataSource
{
	public IEnumerable<Product> GetProducts()
	{
		return new List<Product>() { new Product() { Id = 5, Name = "Fifth" }, new Product() { Id = 6, Name = "Sixth" } };
	}
}

public class FileSource : FileSourceBase, IProductDataSource
{
	public IEnumerable<Product> GetProducts()
	{
		return new List<Product>() { new Product() { Id = 3, Name = "Third" }, new Product() { Id = 4, Name = "Fourth" } };
	}
}

public class DatabaseSource : DatabaseSourceBase, IProductDataSource
{
	public IEnumerable<Product> GetProducts()
	{
		return new List<Product>() { new Product() { Id = 1, Name = "First" }, new Product() { Id = 2, Name = "Second" } };
	}
}

A common functionality needed from each data source is to search for specific products regardless of the source, e.g. retrieve all products whose name includes “f”. The goal is now to add this function by an extension method. Add a new class to the same folder called DataSourceExtensions and make it… …public and static, as you know by now. Double-check that the namespace is the same as for the IProductDataSource interface. This is so that the extension will be available anywhere the interface is available without the need to add extra using statements.

Add the following stub extension method which extends the interface:

public static IEnumerable<Product> SearchProduct(this IProductDataSource source, string searchTerm)
{
	return null;
}

It can be called from Main as follows:

IProductDataSource productDataSource = new DatabaseSource();
IEnumerable<Product> products = productDataSource.SearchProduct("f");

We had to import the namespace of the interface but then the SearchProduct extension was readily available. The implementation of the method is simple as each concrete class has a method which returns all products. All we need is some LINQ search:

public static IEnumerable<Product> SearchProduct(this IProductDataSource source, string searchTerm)
{
	return from p in source.GetProducts() where p.Name.ToLower().IndexOf(searchTerm.ToLower()) > -1 select p;
}

As we’re extending an interface, the extension method will be available for all implementing types. There’s no need to cast the concrete type to an interface type. Also, if you get new implementing classes in the future then the extension method will be automatically available for them as well.

Read the next post in this series here.

Events, delegates and lambdas in .NET C# part 6: other scenarios

Introduction

So far in this series we’ve seen the basics of events, delegates and lambdas. We’ve looked at examples of how to define these elements and use them in code.

It’s now time for us to look at some other simulated scenarios where you can use these language elements. In particular we’ll look at the following:

  • Mediator pattern with delegates
  • Asynchronous delegate invocation

Communication across components

Imagine a scenario where you have a dynamic GUI of a Windows application. The components – widgets – can be loaded here and there and they are independent of each other to allow for loose coupling. At the same time they should be able to communicate with each other.

This scenario can be generalised: imagine independent objects that don’t know about other objects but still want to communicate with them in case they are present.

This is a perfect scenario for events and delegates and a pattern called the Mediator pattern. If you don’t know what a mediator is then make sure to read that introduction where the pattern is demonstrated without using events and delegates. With independent components we’ll need a Mediator that acts as a glue for those components. They will only know about the Mediator but not the other objects they are indirectly communicating with.

An additional pattern that is useful in this scenario is the Singleton pattern. If you don’t know what it means then skim through that article to get the basics. The purpose of the singleton in this case is to have only one Mediator class in memory. Otherwise the independent components may reference different mediators.

Note that this post concentrates on the role of delegates and events. If you’d like to extend this example so that it better follows SOLID and abstractions then look through blog entries in the Architecture and patterns section.

Open the project we’ve been working on in this series and add a new C# library called ComponentsMediator. Add a new class to it called Mediator which will be responsible for the communication between the independent components.

Add the following elements to adhere to the singleton pattern. We’ll employ a simple version of the pattern. Read the referenced article to see what some of the other possible solutions are.

private static readonly Mediator _instance = new Mediator();

private Mediator() { }
public static Mediator Instance
{
        get
	{
		return _instance;
	}
}

We’ll simulate the scenario where the user selects a product in a drop down list. We want to update the screen accordingly. Add the following Product class to the project:

public class Product
{
	public int Id { get; set; }
	public string Name { get; set; }
	public DateTime Registered { get; set; }
	public int OnStock { get; set; }
}

Return to Mediator.cs and add the following event handler to the Mediator:

public event EventHandler<ProductChangedEventArgs> ProductChanged;

…where ProductChangedEventArgs looks as follows:

public class ProductChangedEventArgs : EventArgs
{
	public Product Product { get; set; }
}

We’ll raise the event in the following method:

public void OnProductChanged(object sender, Product product)
{
	if (ProductChanged != null)
	{
		ProductChanged(sender, new ProductChangedEventArgs() { Product = product });
	}
}

By allowing the sender to be passed in we show that the original event raiser was an object different from the Mediator. Otherwise all products would “think” that the Mediator raised the event which is not entirely true. Keep in mind that the mediator is only an errrm…, well, a mediator. It mediates between independent objects. We need to see if there’s any listener by checking if ProductChanged is null.

Let’s add a component that will initiate the product selection change. You can think of this object as a combo box where the users can select products:

public class ProductChangeInitiator
{
	public ProductChangeInitiator(int selectedProductId)
	{
		SelectedProductId = selectedProductId;			
	}

	public int SelectedProductId { get; set; }

}

Add another class to the library called ProductChangeSimulation and a method called SimulateProductChange:

public class ProductChangeSimulation
{
        private List<Product> _allProducts = new List<Product>()
	{
		new Product(){Name = "FirstProduct", Id = 1, Registered = DateTime.Now.AddDays(-1), OnStock = 456}
		, new Product(){Name = "SecondProduct", Id = 2, Registered = DateTime.Now.AddDays(-2), OnStock = 123}
		, new Product(){Name = "ThirdProduct", Id = 3, Registered = DateTime.Now.AddDays(-3), OnStock = 987}
		, new Product(){Name = "FourthProduct", Id = 4, Registered = DateTime.Now.AddDays(-4), OnStock = 432}
		, new Product(){Name = "FifthProduct", Id = 5, Registered = DateTime.Now.AddDays(-5), OnStock = 745}
		, new Product(){Name = "SixthProduct", Id = 6, Registered = DateTime.Now.AddDays(-6), OnStock = 456}
	};

	public void SimulateProductChange(ProductChangeInitiator changeInitiator)
	{
		Product selectedProduct = (from p in _allProducts where p.Id == changeInitiator.SelectedProductId select p).FirstOrDefault();
		Mediator.Instance.OnProductChanged(changeInitiator, selectedProduct);
	}
}

We maintain a list of products in a private variable. We let the product change initiator to be passed into the method. We then call the OnProductChanged event handler of the mediator by passing the changeInitiator as the original sender and the selected product.

We now have the components ready in order to raise the event and pass in the necessary parameters. We’ll now need a listener. Add a new class called Warehouse:

public class Warehouse
{
	public Warehouse()
	{
		Mediator.Instance.ProductChanged += (s, e) => { SaveChangesInRepository(e.Product); };
	}

	private void SaveChangesInRepository(Product product)
	{
		Console.WriteLine("About to save the changes for product {0}", product.Name);
	}
}

We subscribe to the ProductChanged event of the mediator where the initiator of the event is unknown to Warehouse. It could be any component in reality: a customer, an e-commerce site, a physical shop, whatever. The Warehouse object won’t care. It only wants to know if there was a change so that it can go on with its job. As you see we declared the event subscription with a lambda.

Add a reference from the main project to the ComponentsMediator library. We can connect the pieces from Program.Main as follows:

ProductChangeInitiator initiator = new ProductChangeInitiator(2);
Warehouse warehouse = new Warehouse();
ProductChangeSimulation simulation = new ProductChangeSimulation();
simulation.SimulateProductChange(initiator);

We simulate the product id #2 was selected and start the simulation. You’ll see that Warehouse correctly displays the message in the console.

Let’s add another listener to the library project. Let’s say that the company CEO is a control freak and wants to be notified of all product changes:

public class CEO
{
	public CEO()
	{
		Mediator.Instance.ProductChanged += (s, e) => 
		{ 
			Console.WriteLine("This is the CEO speaking. Well done for selling {0}", e.Product.Name); 
		};
	}
}

Extend the code in Main as follows:

ProductChangeInitiator initiator = new ProductChangeInitiator(2);
Warehouse warehouse = new Warehouse();
CEO ceo = new CEO();
ProductChangeSimulation simulation = new ProductChangeSimulation();
simulation.SimulateProductChange(initiator);

You’ll see that the CEO is very happy now. We effortlessly added another listener to the product change. The CEO, Warehouse and ProductChangeInitiator objects don’t know about each other. This ensures that the components remain loosely coupled. The listeners won’t care where the notification is coming from, they are only connected to the mediator.

Asynchronous delegates

Let’s look at how asynchronous operations can be applied to delegates. Insert a new C# library to the project called AsyncDelegates. Insert a new class called AsynchronousProcessSimulation. Imagine that we start a long process and want to be notified of the progress made. Insert the following method that represents our lengthy process:

private void DoProgress(int maxValue)
{
	for (int i = 0; i <= maxValue; i++)
	{
		Console.WriteLine("Time : {0}", i);
		Thread.Sleep(50);
	}
}

We want to use a delegate to wire the information to the DoProgress method. We’ll do it with a private delegate:

private delegate void ShowProgressDelegate(int status);

Insert the following public entry point that initiates the delegate:

public void StartReporting()
{
	ShowProgressDelegate progressDelegate = new ShowProgressDelegate(DoProgress);
}

Let’s say that we want to invoke this delegate asynchronously. Delegates have a built-in method called BeginInvoke which comes in very handy. It will spin up a separate thread that will call into DoProgress. We can pass in the value for the maxValue parameter, a callback function and an additional object input which will be null in this example. We don’t need a callback either. Add the following async call to StartReporting:

progressDelegate.BeginInvoke(500, null, null);
Console.WriteLine("Finishing the StartReporting method.");

Insert a reference to this project from the main project. You can test the async delegate as follows:

AsynchronousProcessSimulation asyncSimulation = new AsynchronousProcessSimulation();
asyncSimulation.StartReporting();

You’ll see that “Finishing the StartReporting method.” is printed in the console after the delegate has been invoked on a different thread proving the point that BeginInvoke did in fact spawn up a new thread. The lengthy operation just keeps running in the background.

This post finishes this series on delegates and events. I hope you have learned some new stuff that you can use in your own project.

Events, delegates and lambdas in .NET C# part 5: lambda, Func, Action

Introduction

In this post we’ll continue our discussion by diving into the following topics:

  • Lambdas
  • Func of T,TResult
  • Action of T

Lambdas

Lambdas fit very well into the topic of events and delegates. We touched upon anonymous methods at the end of the previous post:

superman.WorldSavingCompleted += delegate(object sender, WorldSavingCompletedEventArgs e)
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
};

Anonymous methods are a good way to get going with lambdas as they have a similar syntax. However, lambdas are more concise. The following is the lambda equivalent of the anonymous method:

superman.WorldSavingCompleted += (s, e) => 
{
	StringBuilder superHeroMessageBuilder = new StringBuilder();
	superHeroMessageBuilder.Append("Superhero has saved the world! Name: ").Append(e.Saviour)
		.Append(", time spent saving the world: ").Append(e.HoursItTookToSaveWorld).Append(", message from the superhero: ")
		.Append(e.MessageFromSaviour);
	Console.WriteLine(superHeroMessageBuilder.ToString());
};

In case the method body is a single statement then you can leave out the curly braces:

superman.WorldSavingCompleted += (s, e) => Console.WriteLine("World saved by " + e.Saviour);

Note how you can access the properties of the event args without having to declare the exact type in the parameter list.

The structure of a lambda expression is the following:

  • Method parameters, in this case (s, e). If there are no input params then this simply becomes (). The compiler will infer the parameter types from the delegate signature. That’s how you could access the Saviour property of the WorldSavingCompletedEventArgs parameter
  • The parameters are followed by the lambda operator ‘=>’. It separates the input parameters from the method body
  • The method body: the parameters defined within the parenthesis will be passed into this inline method

Lambdas with custom delegates

Open the console application we’ve been working on in this series. Add a new class called ProcessIntegers:

public class ProcessIntegers
{
	public void DoAction(int firstInteger, int secondInteger)
	{
	}
}

At first this doesn’t look very clever: we don’t know how the integers will be processed and the method doesn’t return anything. However, by now we know that with delegates and events we can return multiple values from a void method. The goal here is to generalise the way two integers are handled: multiply them, add them etc. Instead of guessing what a client may want to do with the integers and writing 10 methods we’ll let the client define the operation.

In Program.cs insert the following custom delegate:

public delegate int IntegerOperationDelegate(int first, int second);

So it takes two integers and returns an integer. Let’s extend the DoAction method so that it accepts a delegate of this type:

public void DoAction(int firstInteger, int secondInteger, IntegerOperationDelegate del)
{
	int result = del(firstInteger, secondInteger);
	Console.WriteLine(result);
}

So we invoke the delegate in the method body and print out the result. The method allows the caller to pass in a custom delegate so that the DoAction method doesn’t have to be hard coded as far as processing the two integers are concerned. The DoAction method will have no knowledge about the exact delegate passed in which allows for the construction of loosely coupled classes. You can call DoAction from Main using lambdas. Here’s the first integer processor:

IntegerOperationDelegate addIntegersDelegate = (f, s) => f + s;

Looks weird if you see this for the first time, right? You’ll now recognise the input parameters and the lambda operator. Recall that the signature must match the delegate signature hence the (f, s) bit which stand for the first and second integers. The ‘f + s’ bit looks strange as there’s no return statement. It is added by the compiler for you in case there are no curly braces. It is inferred from the delegate signature that you’d like to add two numbers and return the result. A more obvious way of declaring this delegate is the following:

IntegerOperationDelegate addIntegersDelegate = (f, s) => { return f + s; };

Let’s add a couple more delegates:

IntegerOperationDelegate addSquaresOfIntegersDelegate = (f, s) => (f * f) + (s * s);
IntegerOperationDelegate doSomethingRandomDelegate = (f, s) => (f + 3) * (s + 4);

We can then call DoAction as follows:

ProcessIntegers processIntegers = new ProcessIntegers();
processIntegers.DoAction(4, 5, addSquaresOfIntegersDelegate);
processIntegers.DoAction(4, 5, doSomethingRandomDelegate);

So it’s up to the caller to inject the correct rule on how to process the integers. The DoAction method will happily invoke the delegate without having prior knowledge on what’s going to happen to them.

These were a couple of simple examples on how custom delegates work with lambdas.

In the next sections we’ll see how to work with the delegates built into the .NET framework.

Action of T

Action of T represents a delegate that accepts a single parameter and returns no value. The Action object is of type ‘delegate’. You can pass in any object of type T. With Action of T you can skip declaring your delegate as ‘delegate void NameOfDelegate(params)’. Action of T provides a shorter solution to that as it already encapsulates a delegate. You can declare an Action as follows:

Action<string> actionOfString = MatchingActionOfT;
actionOfString("Test");

…where MatchingActionOfT is a method that takes a string to make sure it matches the delegate signature:

private static void MatchingActionOfT(string inputs)
{
	Console.WriteLine(inputs);
}

What if you need to pass in more parameters? That’s no problem as Action of T has 16 versions ranging from…

Action<in T>

…to

Action<in T1, in T2, ... , in T16>

If 16 separate input parameters are not enough then you need to seriously review your code.

You can even assign built-in methods to the Action if the method signature is correct:

Action<string> consoleString = Console.WriteLine;
consoleString("Test from console.");

Extend the ProcessIntegers class with the following method:

public void DoAction(int firstInteger, int secondInteger, Action<int, int> action)
{
        action(firstInteger, secondInteger);
	Console.WriteLine("Paramaters passed: {0}, {1}", firstInteger, secondInteger);
}

In Main we can declare our action:

Action<int, int> voidAction = (f, s) => Console.WriteLine(f + s);

…and then invoke it indirectly:

ProcessIntegers processIntegers = new ProcessIntegers();
processIntegers.DoAction(2, 2, voidAction);

The overloaded DoAction method will invoke the voidAction Action for us which will result in a printout on the console window.

Function of T, TResult

This is similar to Action of T. Its type is still ‘delegate’. The key difference is that it has a return value of type TResult. Just like with Actions you can pass in 16 parameters. The return type is always the last element in the type declaration. A function that takes two integers and returns a double will look like this:

Func<int, int, double> func = MatchingFuncOfT;

…and a matching method will take the following form:

private double MatchingFuncOfT(int first, int second)
{
	return first / second;
}

The Func delegate can be invoked as usual:

double res = func(3, 2);

In case the Func doesn’t accept any parameters then the single type declaration will be the return type:

Func<out T>

Just like with Action of T this method saves you the time and code declaring the custom delegate.

Previously in this post we added a custom delegate and created instances of that delegate using lambdas:

IntegerOperationDelegate addIntegersDelegate = (f, s) => f + s;
IntegerOperationDelegate addSquaresOfIntegersDelegate = (f, s) => (f * f) + (s * s);
IntegerOperationDelegate doSomethingRandomDelegate = (f, s) => (f + 3) * (s + 4);

We can achieve the same goal as follows:

Func<int, int, int> addIntegersFunction = (f, s) => f + s;
Func<int, int, int> addSquaresOfIntegersFunction = (f, s) => (f * f) + (s * s);
Func<int, int, int> doSomethingRandomFunction = (f, s) => (f + 3) * (s + 4);

Insert the following method into ProcessIntegers:

public void DoAction(int firstInteger, int secondInteger, Func<int, int, int> action)
{
	int res = action(firstInteger, secondInteger);
	Console.WriteLine("Func result: {0}", res);
}

We invoke the action in the usual way of invoking methods. We get the result and print it on the Console. Just like before, the DoAction method is not aware of what’s going on within the action.

We can call the overloaded DoAction method from Main as follows:

processIntegers.DoAction(2, 2, addIntegersFunction);
processIntegers.DoAction(4, 5, addSquaresOfIntegersFunction);
processIntegers.DoAction(4, 5, doSomethingRandomFunction);

Lambdas and Funcs in LINQ

Lambdas and Funcs are often used in LINQ when querying objects. Add a Product object to the solution:

public class Product
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Description { get; set; }
	public int OnStock { get; set; }
}

Add a ProductService with a list of all products and a method stub:

public class ProductService
{
	private List<Product> _allProducts = new List<Product>()
	{
		new Product(){Description = "FirstProduct", Id = 1, Name = "FP", OnStock = 456}
		, new Product(){Description = "SecondProduct", Id = 2, Name = "SP", OnStock = 123}
		, new Product(){Description = "ThirdProduct", Id = 3, Name = "TP", OnStock = 987}
		, new Product(){Description = "FourthProduct", Id = 4, Name = "FoP", OnStock = 432}
		, new Product(){Description = "FifthProduct", Id = 5, Name = "FiP", OnStock = 745}
		, new Product(){Description = "SixthProduct", Id = 6, Name = "SiP", OnStock = 456}
	};

	public void PlayWithLinq()
	{
	}
}

Start typing the following statement in PlayWithLinq:

IEnumerable<Product> filteredProducts = _allProducts.Where(

As you type ‘(‘ IntelliSense will show that Where accepts a Function of Product that returns a boolean. This means that the function will look at the Product objects in _allProducts and if there’s a match, i.e. the Func returns true, then the Product will be added to the List of products. Now that we know lambdas we can have something like this:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => p.OnStock > 300);

‘p’ is the input parameter to the function, which will be a Product object from _allProducts. Then we have the lambda operator followed by the method body which returns a boolean. Just like above we can explicitly show the return statement if we want to:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => { return p.OnStock > 300; });

You can call the input parameter as you wish: ‘p’, ‘prod’, ‘mickeymouse’ etc. The function takes a single parameter so we can omit the parenthesis, but you can also put ‘(p)’ if you want to. If the function accepts more parameters then we would need to add them within parenthesis. You can then simply iterate through the filtered products:

foreach (Product prod in filteredProducts)
{
	Console.WriteLine(prod.Id);
}

Call the method like this:

ProductService productService = new ProductService();
productService.PlayWithLinq();

…and you’ll see the filtered ids appear.

You can have multiple filtering criteria. As long as the method body returns a bool and accepts a Product it will be fine:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => p.OnStock > 300 && p.Id < 4).OrderBy(p => p.Name);

We can extend our filter by an OrderBy clause which accepts a Function of T and returns a key of type TKey. The key is the property we want to order by:

IEnumerable<Product> filteredProducts = _allProducts.Where(p => p.OnStock > 300).OrderBy(p => p.Name);

Read the finishing post on this topic here.

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

ARCHIVED: Bite-size insight on Cyber Security for the not too technical.