Sum of TimeSpan in C #?

11

In the sum of two variables of type TimeSpan with the language I could see that it happens as if it were a mathematical operation of two simple numbers, example :

TimeSpan t1 = TimeSpan.ParseExact("00:01:45", "c", CultureInfo.InvariantCulture);
TimeSpan t2 = TimeSpan.ParseExact("00:02:45", "c", CultureInfo.InvariantCulture);

TimeSpan t3 = t1 + t2;

The final result of this is 4 minutes and 30 seconds in variable t3 .

Two structures theoretically should not do sum operations transparently, I would like to know the following:

  • How this sum operation of the two structures works TimeSpan ?
  • This can be done in other classes as a way to make it easier to perform mathematical or conversational operations,
asked by anonymous 06.06.2017 / 22:27

2 answers

10
  

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;
    
06.06.2017 / 22:42
8

The sum between the two structures works because the language allows you to overhead operator .

  

How does this sum operation of the two TimeSpan structures work?

This is defined in the creation of the structure, in the same way that fields, the constructor, etc. are defined. It is a static method with any return type that contains the reserved word operator .

Something like:

public static TimeSpan operator +(TimeSpan c1, TimeSpan c2) 
{
    // fazer a operação 
    return timeSpan;
}
  

This can be done in other classes as a way to facilitate math or conversion operations, are there examples to demonstrate?

Yes. There are a few, basically you can do anything. A basic example is a structure that represents two-dimensional vectors.

I defined a method to do the sum of two vectors, overloading the + operator and a conversion from int to Vector - this conversion is called #:

struct Vector
{
    public int ComponenteX;
    public int ComponenteY;

    public Vector(int cX, int cY){
        ComponenteX = cX;
        ComponenteY = cY;
    }

    public static Vector operator +(Vector v1, Vector v2) 
    {
        return new Vector(v1.ComponenteX + v2.ComponenteX, v1.ComponenteY + v2.ComponenteY);
    }

    public static implicit operator Vector(int componenteX)
    {
        return new Vector(componenteX, 0);
    }

    public override string ToString()
    {
        return $"{ComponenteX}, {ComponenteY}";
    }
}

See working in .NET Fiddle.

    
06.06.2017 / 22:41