Classes are the core of the C# language and the .NET framework is filled with thousands of classes that we cannot edit, such as the System.Linq.Enumerable
class. This is where extension methods shine; being able to extend a class without recompiling it or using inheritance. In this recipe, we will extend a custom User
class to manipulate properties and return a formatted string.
Refer to the UserExtensions.cs
and Models/Users.cs
file in the ExtensionMethods.Library
project for the extension methods and class. These methods are used in the Program.cs
file in the ExtensionMethods.Console
project.
The following code shows the custom class we will be working with:
public class User { private int _id; public int UserId { get { return _id; } set { _id = value; } } public string FirstName { get; set; } public string LastName { get; set; } }
The following code shows two extension methods:
/// <summary> /// Gets the full name of the user by merging all other names if no FullName is set. /// </summary> /// <param name="value"></param> /// <returns></returns> public static string GetFullName(this User value) { return string.Format("{0} {1}", value.FirstName, value.LastName); } /// <summary> /// Parses and set a 2 word name into first and last names /// </summary> /// <param name="value"></param> /// <param name="fullName"></param> public static void SetNames(this User value, string fullName) { //the default delimiter is whitespace if no params are passed. string[] names = fullName.Split(); value.FirstName = names[0]; value.LastName = names[1]; }
The following code shows shows the use of the extension methods:
User user = new User { FirstName = "Shawn", LastName = "Mclean" }; //should be "Shawn Mclean" string fullName = user.GetFullName(); //user.FirstName should be "Trevoir" and user.LastName "Williams" user.SetNames("Trevoir Williams");
Here, we created a User
class in which we will add additional functionality by using extension methods. The first extension method is GetFullName
which accesses the object's properties and combines them to return an output. The second extension method is SetNames
, which actually modifies the properties of the object.
Accessing and modifying object properties and calling public methods of the object inside the extension method is straightforward.
There are some key points to note when extending classes:
Privates are inaccessible: As stated earlier, extension methods are not part of the class; hence, they have no access to the private fields or methods of the object. The following extension method would never work when trying to access a private
_id
variable:public static string GetId(this User value) { //Syntax error would be thrown here. return value._id; }
Modifying the instance object: When modifying the instance object, ensure not to assign a new instance to the variable, this will lead to a new instance being created for the duration of the extension method's scope and will not actually modify the caller instance. The following is a demonstration of this:
public static void ChangeName(this User value, string firstName) { value = new User { FirstName = firstName, LastName = value.LastName }; }
The value of
FirstName
in the original instance will still be the same after execution.
In this recipe, we have understood the fundamentals of working with a class and a few quirks.