How does this sum operation of the two TimeSpan structures work?
This works because C # allows overhead operators , defining static methods, using the operador
keyword.
To overload an operator it is necessary to create in the class a static method called with the symbol of the operator that is being overloaded.
For unary operators the method declares a parameter, in the case of binary operators two parameters.
The parameter (s) must be of the same type as the class / structure that the operator declares.
In the case of TimeSpan the method looks like this:
public static TimeSpan operator +(TimeSpan t1, TimeSpan t2)
{
return t1.Add(t2);
}
Out of curiosity, the method add () looks like this:
public TimeSpan Add(TimeSpan ts) {
long result = _ticks + ts._ticks;
// Overflow if signs of operands was identical and result's
// sign was opposite.
// >> 63 gives the sign bit (either 64 1's or 64 0's).
if ((_ticks >> 63 == ts._ticks >> 63) && (_ticks >> 63 != result >> 63))
throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong"));
return new TimeSpan(result);
}
This can be done in other classes as a way to facilitate math or conversion operations, are there examples to demonstrate?
Yes, this can be applied to any structure / class, you just need to overload the operators you want to make available.
Example of overloading the +
operator on a structure that represents a complex number.
public struct Complex
{
public int real;
public int imaginary;
public Complex(int real, int imaginary)
{
this.real = real;
this.imaginary = imaginary;
}
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);
}
}
With regard to conversions, you can declare them implicitly or explicitly.
Example of Using a Type Conversion Operator to Allow the implicit conversion (without using cast ) of that type into another.
class Digit
{
public Digit(double d) { val = d; }
public double val;
// Conversão de Digit to double
public static implicit operator double(Digit d)
{
return d.val;
}
// Conversão de double para Digit
public static implicit operator Digit(double d)
{
return new Digit(d);
}
}
Example usage:
Digit dig = new Digit(7);
//Conversão implícita de Digit para double
double num = dig;
//Conversão implícita de double para Digit
Digit dig2 = 12;
Example of Using a Type Conversion Operator to Allow explicit conversion (invoked using cast ) of that type in another.
class Celsius
{
public Celsius(float temp)
{
degrees = temp;
}
public static explicit operator Fahrenheit(Celsius c)
{
return new Fahrenheit((9.0f / 5.0f) * c.degrees + 32);
}
public float Degrees
{
get { return degrees; }
}
private float degrees;
}
Example usage:
Fahrenheit fahr = new Fahrenheit(100.0f);
//Conversão explicita de Fahrenheit para Celsius
Celsius c = (Celsius)fahr;