Coder Perfect

Static implicit operator

Problem

I recently came across the following code:

 public static implicit operator XElement(XmlBase xmlBase)
 {
     return xmlBase.Xml;
 }

What does it mean to have a static implicit operator?

Asked by Bart

Solution #1

This is a transformational operator. It implies you can write the following code:

XmlBase myBase = new XmlBase();
XElement myElement = myBase;

And the compiler is unconcerned! The conversion operation will be invoked at runtime, with myBase as the argument and a valid XElement as the result.

It’s a means for you to inform the compiler as a developer:

Answered by Rex M

Solution #2

Because of the implicit operator, you can implicitly transform XmlBase to XElement.

XmlBase xmlBase = WhatEverGetTheXmlBase();
XElement xelement = xmlBase;   
//no explicit convert here like: XElement xelement = (XElement)xmlBase;

Answered by Cheng Chen

Solution #3

Another intriguing application (which Unity used to verify if an object (and so a MonoBehavior instance) is null):

public static implicit operator bool (CustomClass c)
{
    return c != null;
}

It’s worth noting that the code must be included within the class (CustomClass in this case). As a result, you may do something like this:

void Method ()
{
    CustomClass c1 = null;
    CustomClass c2 = new CustomClass ();

    bool b1 = c1; // is false
    bool b2 = c2; // is true

    if (!c1 && c2)
    {
        // Do stuff
    }
}

Using it to convert one of your classes to another is probably the most well-known application. However, utilizing them with basic kinds is also worth considering… yet I’ve only seen it suggested a few times.

Answered by Battle

Solution #4

It’s an implicit conversion operator (rather than an explicit conversion operator, which requires the (type) conversion syntax).

Answered by Andrew Barber

Solution #5

My two cents.

This comes in handy when unit testing an immutable entity that will be utilized with the Builder Pattern.

Let’s say you have an immutable Employee domain object. When we wish to stick to the DDD style, we usually do this.

public class Employee 
{ 
  public Employee(int id, string firstname, string lastname, DateTime birthdate, string street) 
  { 
    this.ID = id; 
    this.FirstName = firstname; 
    this.LastName = lastname; 
    this.BirthDate = birthdate; 
    this.Street = street; 
  } 

  public int ID { get; private set; } 
  public string FirstName { get; private set; } 
  public string LastName { get; private set; }
  public DateTime BirthDate { get; private set; } 
  public string Street { get; private set; } 

  public string getFullName() 
  { 
    return this.FirstName + " " + this.LastName; 
  } 

  public int getAge() 
  { 
    DateTime today = DateTime.Today;
    int age = today.Year - BirthDate.Year;

    if (BirthDate > today.AddYears(-age))
      age--;

    return age; 
  } 
}

You can now have an employee builder like the one below (inside of the test project). We have this implicit operator at the end, as you can see.

public class EmployeeBuilder
{ 
  private int id = 1; 
  private string firstname = "first"; 
  private string lastname = "last"; 
  private DateTime birthdate = DateTime.Today; 
  private string street = "street"; 
  public Employee Build() 
  { 
    return new Employee(id, firstname, lastname, birthdate, street); 
  } 
  public EmployeeBuilder WithFirstName(string firstname) 
  { 
    this.firstname = firstname; 
    return this; 
  } 
  public EmployeeBuilder WithLastName(string lastname) 
  { 
    this.lastname = lastname; 
    return this; 
  } 
  public EmployeeBuilder WithBirthDate(DateTime birthdate) 
  { 
    this.birthdate = birthdate; 
    return this; 
  } 
  public EmployeeBuilder WithStreet(string street) 
  { 
    this.street = street; 
    return this; 
  } 
  public static implicit operator Employee(EmployeeBuilder instance) 
  { 
    return instance.Build(); 
  } 
}

You can now create a test class for your employees, such as this.

public class EmployeeTest
{
  [Test]
  public void GetFullNameReturnsCombination()
  { 
    // Arrange
    Employee emp = new EmployeeBuilder().WithFirstName("Vivek").WithLastName("Koppula"); 
    // Act
    string fullname = emp.getFullName(); 
    // Assert
    Assert.That(fullname, Is.EqualTo("Vivek Koppula")); 
  } 

  [Test] 
  public void GetAgeReturnsCorrectValue() { 
  // Arrange
  Employee emp = new EmployeeBuilder().WithBirthDate(new DateTime(1983, 1,1)); 
  // Act
  int age = emp.getAge(); 
  // Assert
  Assert.That(age, Is.EqualTo(DateTime.Today.Year - 1983)); 
  } 
}

This simplifies unit testing by allowing us to generate the employee using only the relevant parameters.

In the first test, for example, we simply care about the first and last names. So we don’t have to worry about age or street in the first scenario.

In the second scenario, we’re only interested with age and nothing else.

Article References.

Answered by VivekDev

Post is based on https://stackoverflow.com/questions/4273743/static-implicit-operator