I want to create a generic extension method that will set a value to an Object or a Struct if their value equals to their default value.
so i have the following code:
public static void setIfNull<T>(this T i_ObjectToUpdate, T i_DefaultValue)
{
if (EqualityComparer<T>.Default.Equals(i_ObjectToUpdate, default(T)))
{
i_ObjectToUpdate = i_DefaultValue;
}
}
and here is a call example:
public OrganizationalUnit CreateOrganizationalUnit(OrganizationalUnit i_UnitToCreate)
{
i_UnitToCreate.EntityCreationDate.setIfNull(DateTime.Now); //Here is a call
i_UnitToCreate.EntityLastUpdateDate.setIfNull(DateTime.Now); //And another one
m_Context.DomainEntities.Add(i_UnitToCreate);
return i_UnitToCreate;
}
I don’t know if it have anything to do with it but i use entity framework and MVC.
What actually happens in a debugger I see that the line in the extension method i_ObjectToUpdate = i_DefaultValue; is working and the values are changes but when the debugger gets out of the extension method I see that the value of i_UnitToCreate.EntityCreationDate remains unchaged.
Any ideas what went wrong ?
You have two references in your code. One is
i_UnitToCreate.EntityCreationDatewhich points to some address in memory. And other isi_ObjectToUpdatein your extension method, which initially also points to that address (you are creating copy of address when passingi_UnitToCreate.EntityCreationDatereference to your method). Later you change second reference to point on other object in memory, but that does not change first reference, because they are independent.Workaround
You can use expression to pass property selector (not property value) to extension method. Retrieve value from compiled expression. If it is default value, then with reflection (you can easily get
PropertyInfoby casting member expression) set new value. Usage:PS There is one remark about my first answer – I thought about generic
Ttype as a reference type, when talked about copying reference values. With value types (as DateTime) whole object is copied. It does not change result (you can’t assign new value), but needs to be mentioned.