### c#

#### Overloading with the same data types

```As a technical exercise I tried to create different methods to calculate a triangle perimeter.
When the three edges are given - the task is straightforward,
but when we get two edges and the angle between them or one edge and its two edges - we should apply some trigonometric manipulations.
In order to distinguish among the three cases, I declared the edges as decimals and the angles as floats, and thus gave the system a hint which method to overload (eg: decimal & float & decimal => 2 edges and an angle).
This isn't the most elegant solution because the datatype is not supposed to be used in order to transfer information.
Another option is to add another variable which will get the value 1 or 2 or 3 as an indication what type of problem is it, but in this case there is no need for overloading..
Is there a way to create three overloaded methods, each one gets three decimals, and to add somehow an indication what do the three variables symbolize (and which method to use)?
```
```Using different types is the correct way. Using decimal and float is the wrong way. You should have created two (immutable) struct, Length and Angle, explicitly castable to/from 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);
}
Use:
Length length1 = (Length)1.0m;
Length length2 = (Length)2.0m;
Length length3 = (Length)3.0m;
Length perimeter = Perimeter(length1, length2, length3);
Some notes:
I have implemented the operator+ inside the Length/Angle (Length with Length and Angle with Angle).
The naming is terrible. I would call them Meters and Radians for example.
Other operators can be easily added (probably the operator- would be useful), and interfaces (IComparable, IComparable<>, IEquatable<>, IFormattable, ISerializable) and the other operators (==, !=, <=...).
If you rename the structs to Meters and Radians, change the ToString() to print the units of measure.
```
`Use named parameters and implement third argument as optional. See here.`

Encrypt Message