Custom Explicit and Implicit Operators in C#
I recently had a friend ask me about my use of implicit operators. I’ve been using them for a while now, but don’t think they’ve gained much traction for some reason, as I rarely come across code where they’ve been implemented.
Using implicit or explicit operators at their base implementation is quite easy, there’s a few simple rules to follow when implementing them:
- The operator must be enclosed in the class or partial class that it converts
- It must accept only 1 parameter
There’s a few other rules, but those are the two important ones to follow when getting started.
Implicit Operator
public class CustomerDTO
{
public static implicit operator CustomerDTO(Customer entityObject)
{
}
}
Pretty easy to implement, and you implement explicit operators the same way. The major difference being the required explicit call on an explicit operator such as:
CustomerDTO.ToCustomer()
For this example, I’ve created a very small model of a customer object, with addresses. This model is not connected to a database, and utilizes the model designer of the Entity Framework 4.0.
I’ve also wired up to POCO (Plain old CLR Objects) objects, as DTO’s (data transfer objects). The scope of this entry is not to describe why you’d use POCO or transfer objects, but if you’re using them, and doing manual conversions this will save you a LOT of headache. :)
public class CustomerDTO
{
int id { get; set; }
string name { get; set; }
string taxid { get; set; }
Status active { get; set; }
IEnumerable<AddressDTO> addresses { get; set; }
}
public enum Status
{
Inactive, //=0
Active //=1
}
public class AddressDTO
{
int id { get; set; }
string address1 { get; set; }
string city { get; set; }
string state { get; set; }
string zip { get; set; }
int Customerid { get; set; }
}
Once we have our model in place, and our POCO objects created, we can get into the meat of the operators we want to implement.
Lets start with the CustomerDTO operator:
public static implicit operator CustomerDTO(Customer entityObject)
{
return new CustomerDTO
{
taxid = entityObject.TaxID,
name = entityObject.Name,
id = entityObject.Id,
addresses = entityObject.Addresses,
active = (Status)Enum.Parse(typeof(Status), entityObject.Active)
};
}
You’ll notice that when you implement this code, you receive this error:
This is exactaly where implicit operators come in! When we go and define the implicit operator for the Address, we’ll solve our problem here:
public static implicit operator AddressDTO(Address entityAddress)
{
return new AddressDTO
{
id = entityAddress.Id,
address1 = entityAddress.Address1,
city = entityAddress.City,
state = entityAddress.State,
zip = entityAddress.Zip,
Customerid = entityAddress.CustomerId
};
}
The finished CustomerDTO implicit operator:
public static implicit operator CustomerDTO(Customer entityObject)
{
CustomerDTO returnObject = new CustomerDTO()
{
taxid = entityObject.TaxID,
name = entityObject.Name,
id = entityObject.Id,
active = (Status)Enum.Parse(typeof(Status), entityObject.Active)
};
// Do this longhand for visibility
// Without the implicit operator for AddressDTO we could not use the ().Add(e) without an implicit cast error
entityObject.Addresses.ToList().ForEach(e => returnObject.addresses.ToList().Add(e));
return returnObject;
}
Now all that would be left, would be to extend the partial classes of our Entity Framework objects, such as the Customer and Address to return DTO objects
Now, anywhere in our business logic we can use implicit converstion such as
AddressDTO = Address
Address = AddressDTO
Customer = CustomerDTO
CustomerDTO = Customer
Hope that makes life easier ---
Code happy!