使用相同的数据类型重载

时间:2017-04-13 08:16:00

标签: c# operator-overloading

作为一项技术练习,我试图创建不同的方法来计算三角形周长。

当给出三条边时 - 任务很简单, 但是当我们得到两条边和它们之间或一条边和它的两条边之间的角度时 - 我们应该应用一些三角函数操作。

为了区分这三种情况,我将边缘称为小数,将角度称为浮点数,从而为系统提供了一个提示哪种方法可以过载(例如:十进制和放大&十进制=> 2边缘和一个角度)。

这不是最优雅的解决方案,因为不应该使用数据类型来传输信息。 另一种选择是添加另一个变量,它将获得值1或2或3作为指示它是什么类型的问题,但在这种情况下不需要重载..

有没有办法创建三个重载方法,每个方法获得三位小数,并以某种方式添加三个变量符号化的指示(以及使用哪种方法)?

2 个答案:

答案 0 :(得分:1)

使用不同类型是正确的方法。使用decimalfloat是错误的方法。您应该已经创建了两个(不可变的)struct LengthAngle,可以显式地转换为decimal / double

public struct Length
{
    public readonly decimal Value;

    public Length(decimal length)
    {
        Value = length;
    }

    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        if (obj == null || !(obj is Length))
        {
            return false;
        }

        return Value == ((Length)obj).Value;
    }

    public override string ToString()
    {
        return Value.ToString();
    }

    public static explicit operator Length(decimal value)
    {
        return new Length(value);
    }

    public static explicit operator decimal(Length length)
    {
        return length.Value;
    }

    public static Length operator+(Length length1, Length length2)
    {
        return new Length(length1.Value + length2.Value);
    }
}

public struct Angle
{
    public readonly decimal Value;

    public Angle(decimal angle)
    {
        Value = angle;
    }

    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        if (obj == null || !(obj is Angle))
        {
            return false;
        }

        return Value == ((Angle)obj).Value;
    }

    public override string ToString()
    {
        return Value.ToString();
    }

    public static explicit operator Angle(decimal value)
    {
        return new Angle(value);
    }

    public static explicit operator decimal(Angle angle)
    {
        return angle.Value;
    }

    public static Angle operator +(Angle angle1, Angle angle2)
    {
        return new Angle(angle1.Value + angle2.Value);
    }
}

public static Length Perimeter(Length length1, Length length2, Length length3)
{
    return length1 + length2 + length3;

    // Or
    //return new Length(length1.Value + length2.Value + length3.Value);
}

使用:

Length length1 = (Length)1.0m;
Length length2 = (Length)2.0m;
Length length3 = (Length)3.0m;
Length perimeter = Perimeter(length1, length2, length3);

一些注意事项:

  • 我已在operator+ / LengthAngle实施Length LengthAngle Angle }})。

  • 命名很糟糕。我会称他们为MetersRadians

  • 可以轻松添加其他运算符(可能operator-可能有用)和接口(IComparableIComparable<>IEquatable<>,{{1} },IFormattable)和其他运算符(ISerializable==!= ...)。

  • 如果您将结构重命名为<=Meters,请更改Radians以打印度量单位。

答案 1 :(得分:-1)

使用命名参数并将第三个参数实现为可选参数。请参阅here