reza ghasemi
Reza Ghasemi

Follow

Reza Ghasemi

Follow

deepening into the implicit operator and explicit operator in c#

reza ghasemi's photo
reza ghasemi
·Dec 31, 2022·

4 min read

Play this article

Table of contents

  • what is the implicit operator and explicit operator
  • deeping into the topic

what is the implicit operator and explicit operator

In C#, operator overloading allows you to define custom behavior for certain operators when applied to a class or struct types. This can be useful for creating more intuitive and natural syntax for working with your own types. There are two types of operator overloading in C#: implicit and explicit.

Implicit operator overloading is used to define automatic type conversions for your custom types. This means that you can use the built-in type conversion functions, such as (int) or (double), to convert an instance of your custom type to a built-in type. For example, you might define an implicit operator to convert a Money type to a double type, so that you can perform arithmetic operations on money values using the standard arithmetic operators.

Here's an example of how you might define an implicit operator for converting a Money type to a double type:

public struct Money
{
    private double _value;
    public Money(double value)
    {
        _value = value;
    }

    public static implicit operator double(Money money)
    {
        return money._value;
    }
}

With this operator defined, you can now use the Money type in arithmetic expressions as if it were a double:

Money m = new Money(10.50);
double d = m * 2;  // d will be 21.00

Explicit operator overloading is used to define explicit type conversions for your custom types. This means that you have to use a cast operator, such as (int) or (double), to perform the conversion. This is useful when the conversion may not always be safe or meaningful, and you want to require the developer to explicitly indicate their intent to perform the conversion.

Here's an example of how you might define an explicit operator for converting a Temperature type to a double type:

public struct Temperature
{
    private double _value;
    public Temperature(double value)
    {
        _value = value;
    }

    public static explicit operator double(Temperature temperature)
    {
        return temperature._value;
    }
}

With this operator defined, you can now use the Temperature type in arithmetic expressions by explicitly casting it to a double:

Temperature t = new Temperature(70.0);
double d = (double)t + 32.0;  // d will be 102.0

It's important to note that you can only define one of each type of operator for a given type conversion. You can't define both an implicit and an explicit operator for the same type conversion.

deeping into the topic

When you define an operator overloading in C#, the compiler generates a special method to represent the operator. This method is called a "conversion operator," and it has a special syntax that includes the operator keyword and the operator symbol you want to overload.

For example, here's how the compiler would generate the code for the implicit operator we defined earlier for converting a Money type to a double type:

public static double op_Implicit(Money money)
{
    return money._value;
}

The op_Implicit method is the conversion operator for the implicit type conversion from Money to double. It takes a Money instance as its parameter and returns a double value.

Similarly, here's how the compiler would generate the code for the explicit operator we defined earlier for converting a Temperature type to a double type:

public static double op_Explicit(Temperature temperature)
{
    return temperature._value;
}

The op_Explicit method is the conversion operator for the explicit type conversion from Temperature to double. It takes a Temperature instance as its parameter and returns a double value.

When you use an operator in your code, the compiler looks for a corresponding conversion operator to call. If it finds an implicit operator, it will automatically insert a call to the operator when it encounters a type conversion that matches the operator's signature. If it finds an explicit operator, it will only insert a call to the operator if you use a cast operator to explicitly indicate the type conversion.

For example, consider the following code:

Money m = new Money(10.50);
double d = m * 2;

When the compiler encounters the m * 2 expression, it will see that m is a Money type and that it needs to perform a multiplication with a double value. It will then search for an implicit operator that converts a Money type to a double type, and it will find the op_Implicit method we defined earlier. The compiler will then generate the following code to call the op_Implicit method and perform the multiplication:

Money m = new Money(10.50);
double d = op_Implicit(m) * 2;

Let me know if you have any questions :)

Did you find this article valuable?

Support reza ghasemi by becoming a sponsor. Any amount is appreciated!

See recent sponsors Learn more about Hashnode Sponsors
 
Share this