Generics in C Sharp
I wanted to give some demonstrations around the use of Generics in the C# language. Generics are a very valuable tool and have a few benefits to their use, one of which is Type Safety in our classes. If you have been using C# for a while, you will most likely have used
List<T> which implements from numerous interfaces that are part of the
System.Collections.Generics namespace. [You can read about C# List’s on Microsoft’s docs]. You’ll notice that when initializing
new List in C# you must use a special bit of syntax, which looks like this
var stringList = new List<string>();. You must initialize a
List<T> in the following way.
A generic list must have a placeholder for the type it uses, in our example, the placeholder is of data type
string. This offers an advantage over your traditional
ArrayListcollections in C#. The advantage is namely because of type safety, but there is also in many cases the benefit of increased performance and code reuse. If you attempt to add something to a generic list that was initialized with a specific type but then attempt to add something of a different data type you will get a compilation error similar to the following –
Argument 1: cannot convert from 'int' to 'string', this is not the case with an
ArrayList, where you can add an assortment of data types.
var stringList = new List<string>(); stringList.Add(10);//Argument 1: cannot convert from 'int' to 'string'
The above example is a commonly used implementation of how we can use Generics, but what are some other ways, that we can use Generics? Let’s take a look at some different examples.
Often times we will use Generics in our method signatures, this will help to enforce values being passed in as well as increase the level of type-safety. Let’s look at the below code snippet.
The above code may not be useful on its surface however if you are using a method where type-safety and enforcement become necessary, this is a way to do so, while also maintaining code reuse. For example, the above could be used if you wanted to perform a math operation on a float in one implementation, a double in another or an integer. Usually, though the actual use of Generics is applied to the class itself and then applied to the class properties, methods, etc.
Classes and Generics
This way we can create a type-safe class. Hopefully, you can see how the use of generics allows for the reuse of code.
The first example of our GenericsList class shows an ad-hoc implementation for a method that has the must implement the type that is passed in when declaring our class. For example, the implementation would look like this in code when using our class.
GenericList<object> objectList = new GenericList<object>(); object myObject = new object(); objectList.Add(myObject);
Hopefully this helps make sense how the use of
using System.Collections.Generic; works in C#. The class placeholder enforces the later used type. So if we were to then create another instance of our class it would look like the following:
GenericList<string> stringList = new GenericList<string>(); string myString = "FooBaz string"; stringList.Add(myString);
Now for the implementation of our
GenericFields class let’s look at the actual implementation.
GenericFields<string> genricString = new GenericFields<string>("test string"); Console.WriteLine(genricString.value);//test string genricString.value = "new string value"; Console.WriteLine(genricString.value);//new string value //The below code will throw the following compilation error. genricString.value = 10;//cannot implicitly convert type 'int' to 'string'
Advantages of Generics
Reusability: You can use a single generic type definition for multiple purposes in the same code without any method overriding or code modification. For example, you can create a generic method to perform a math operation. You could then use the method to perform the same operation on double float, or int.
Type Safety: Generic data types provide better type safety, especially in the case of collections, which is where you will most likely be using them the most from the
Performance: Generic types provide better performance because they reduce the need for boxing, unboxing, just read this stackoverflow post for more information about this subject.