Introduction
Mapping one object to another is a common task in software development. It involves copying the values of properties from one object to another object of a different type or the same type. In C#, there are several ways to map one object to another, such as AutoMapper, ValueInjecter, etc. However, this article will discuss how to map one object to another in C# without using third-party packages.
In this article, we will map one object to another object, which are the same type and different type. Some properties are same, and some are different in case.
For this, we are going to create three different classes. First is Department, which contains DepartmentId and DepartmentName.
Second is Employee, which contains various types of properties like integer, string, double, DateTime, and also Department.
The third class is NewEmployee which has the same properties as Employee, but here are some properties that are different in case. Also, there are some Nullable properties.
Next, we will create the object of the Employee class with dummy data, as you can see in the below code snippet.
Next, we will create one generic method called Map, which can take any kind of object as input and return given type of data.
As you can see in the above code
- The name of the method is Map, and it is generic, meaning that it can work with any type TDATA.
- This method accepts one parameter of object type, so it can accept any kind of data
- where TDATA: new(): This is a constraint on the generic type TDATA, which ensures that the type has a default constructor. This is necessary because we need to create a new object of type TDATA and copy the values from oldObject to the new object
Create a new object of TDATA in which we will copy data and return it at last.
Then try and catch block starts, and all the code will be inside this block.
Return newObject without copying any data if the old object is null
The above code get the type of TDATA and input object, which is oldObject, and assigns it to newObjType and oldObjType, respectively.
Get the list of all properties of the new object. And check there are any properties exist.
Start foreach loop iteration of the property list. Get property of old object using GetProprty method. It takes the property name as a parameter which is required, and the second one is BindingFlags which is optional.
BindingFlags
is an enumeration that is used to specify the attributes of a member that should be considered when searching for members in reflection. The vertical bars |
are used to combine multiple enumeration values into a single value.
- BindingFlags.Public: Specifies that public members should be included in the search.
- BindingFlags.NonPublic: Specifies that non-public members should be included in the search.
- BindingFlags.Instance: Specifies that instance members should be included in the search.
- BindingFlags.IgnoreCase: Specifies that the search should be case-insensitive. This flag is used when we want to map FirstName and firstname.
- BindingFlags.ExactBinding: Specifies that the search should only return members matching the specified criteria.
By combining these values with the vertical bars, we are telling the reflection API to search for members that are both public and non-public, instance members only (not static), case-insensitive, and that exactly match the specified criteria. This allows us to find the correct property in the source object even if the casing of its name differs from the target object's property.
Next, check that Old Object has the same properties as the new one by checking that oldProp is null. Here we will check two more flags: the property of a new object is writable, and the property of an old object is readable. If we continue without this check, it will throw an error when we get value from the old object and set it in the new object.
Create two new variables oldPropertyType and newPropertyType, and assign type of old and new object property, respectively.
Then we are also going to add a new check that if any property is a generic type and specifically Nullable, then we are going to re-assign the property type variable with its original data type by GetGenericArguments method, which returns an array, and we are going to get first value.
Next, check that both old and new property are the same type. If we do not add this check, we will get an error when the string type property tries to set a value in the integer property.
Get value from the old object by the GetValue method.
Set value in the new object by the SetValue method.
In the last return newObject.
Main employee Object
Try to map the employee object in the new object, which is the same type as the employee object.
Try to Map employee object in new object, which are different type. The Newemployee object is the NewEmployee type.
Overall, the Map
method uses reflection to copy the properties of one object to another object, which may or may not be of the same type. This allows for flexible object mapping without the need for a third-party library.
You can access and download the source code of this from my GitHub.
0 Comments