Can I make this implicit conversion from an operator overload work?

I am trying to overload the division operator in a class to return a double.

I have two classes: Length and Angle. In the Angle class, I have initializers that accept different trigonometric ratios. Here's an example:

public class Angle
{
    public double Degrees;
    public double Minutes;
    public double Etc;

    public Angle(double radians)
    {
        // Main initialization here.
    }

    public static Angle FromTangent(double tangent)
    {
        return new Angle(Math.Atan(tangent));
    }
}

The Length class converts a measurement input into different units of measure. The last method would really make life easy:

public class Length
{
    public double Inches;
    public double Feet;
    public double Meters;
    public double Etc;

    public enum Unit { Inch, Foot, Meter, Etc };

    public Length(double value, Unit unit)
    {
        // Main initialization here.
    }

    public static Length operator /(Length dividend, Length divisor)
    {
        double meterQuotient = dividend.Meters / divisor.Meters;
        return new Length(meterQuotient, Unit.Meter);
    }

    // This is what I want to be able to do.
    public static double operator /(Length dividend, Length divisor)
    {
        double ratio = dividend.Meters / divisor.Meters;
        return ratio;
    }
}

The problem is that the last two methods are ambiguous. I did some research, and implicit conversion seems like the right learning path. I have tried the following methods, which do not seem to be in the correct syntax:

    public static implicit operator double /(Length dividend, Length divisor) { }

    public static double implicit operator /(Length dividend, Length divisor) { }

    public static implicit double operator /(Length dividend, Length divisor) { }

Ultimately

I want to be able to divide two Length objects, and get a double. It is only valid for division though, because it returns a ratio, not a number of units. If this is possible, the implementation would be super easy, and awesome. That's why I want to know if this is possible.

Length opposite = new Length(userInputValue, userSelectedUnitOfMeasure);
Length adjacent = new Length(otherInputValue, otherUnitOfMeasure);

Angle angle = Angle.FromTangent(opposite / adjacent); // ← So cool if this is possible

Can this be done while still being able to keep my other division operator overload?

Jon Skeet
people
quotationmark

A conversion isn't a division - those are two separate operations. You appear to be trying to combine them at the moment.

Fundamentally, it seems that you should remove this operator:

// Kill this
public static Length operator /(Length dividend, Length divisor)

It simply doesn't make sense - as you mentioned, a length divided by a length is a ratio, it's not a length. 5m / 2m is 2.5, not 2.5m.

Once this is removed, there's no ambiguity, so you're fine.

On the other hand, having fields for inches, feet, metres etc seems like a bad idea to me. You may want to have two fields, one of which is the magnitude and the other of which is the unit (probably an enum).

people

See more on this question at Stackoverflow