August 25, 2026

C# implicit and explicit operators

What they are (quick)

  • Implicit operator: defines an automatic conversion from one type to another that the compiler applies without a cast.
  • Explicit operator: defines a conversion that requires a cast and is used when the conversion may lose information or fail.

Syntax (C#)

Implicit:

public static implicit operator TargetType(SourceType s) {
    // create and return TargetType from s
}

Explicit:

public static explicit operator TargetType(SourceType s) {
    // create and return TargetType from s
}

Simple examples

Implicit (safe, no data loss):

struct Meters {
    public double Value;
    public static implicit operator double(Meters m) => m.Value;
    public static implicit operator Meters(double d) => new Meters { Value = d };
}

Meters m = new Meters { Value = 1.5 };
double d = m;        // implicit
Meters m2 = 2.0;     // implicit

Explicit (possible loss/failure):

struct ByteSized {
    public byte Value;
    public static explicit operator ByteSized(int i) {
        if (i < 0 || i > 255) throw new OverflowException();
        return new ByteSized { Value = (byte)i };
    }
}

int x = 300;
ByteSized b = (ByteSized)x; // requires cast; may throw an exception

When to use which

  • Use implicit when the conversion is:
    • Lossless (no precision or semantic loss).
    • Safe and not surprising to callers.
    • Cheap and well-defined in both directions (often).
  • Use explicit when:
    • The conversion can lose information (precision, range).
    • It can throw or fail.
    • It’s potentially surprising or semantically significant.
    • Converting from a wide to a narrower type (e.g., double → int).

Best practices

  • Prefer explicit for any conversion that can lose data or change meaning.
  • Keep conversions simple and obvious; avoid heavy logic or external dependencies.
  • Provide symmetric conversions when sensible (if you define implicit A→B, consider B→A if safe).
  • Document conversions clearly on the type.
  • Consider factory methods (FromX, ToX) when conversion is complex or may fail with domain-specific errors.
  • Avoid implicit conversions between unrelated types to prevent hidden bugs and API surprises.

Common pitfalls

  • Implicit conversions can make code less readable and introduce subtle bugs when multiple conversion paths exist.
  • Overusing implicit can cause ambiguous overload resolution.
  • Throwing exceptions inside conversion operators is allowed but make the operator explicit if exceptions are possible.

AI Generated

No comments: