Deconstruction in C# 7

C# 7 introduces a nice syntax to deconstruct a class and access all members. If you want to support deconstruction for an object you just must write a “Deconstruct” method which contains one or more out parameter which are used to assign class properties to variables. This deconstruction is also supported by the new Tuple struct introduced with C# 7. The following example shows the deconstruction feature used for a tuple and for an own class.

static void Main(string[] args)
{
  (int x, int y) = GetTuple();

  (double width, double height) = GetRectangle();

  Rectangle rect = new Rectangle(1, 2);
  (double a, double b) = rect;
}

private static (int x, int y) GetTuple()
{
  return (1, 2);
}

private static Rectangle GetRectangle()
{
  return new Rectangle(5, 8);
}

class Rectangle
{
  public Rectangle(double width, double height)
  {
    Width = width;
    Height = height;
  }

  public double Width { get; }
  public double Height { get; }

  public void Deconstruct(out double width, out double height)
  {
    width = Width;
    height = Height;
  }
}

 

The assignment of the class properties to the variables is done by the position. So, the variable names and the class property names or tuple element names must not match. Furthermore, it is possible to write several “Deconstruct” methods with different number of elements.

In the first moment this looks like a nice feature which increases the readability of the source code. But it comes with a big issue. As the deconstruction is done be the element positions only it is a source for errors. If you switch elements by mistake, you create an issue which cannot be found by the compiler if the types are equal. This may cost you a lot of debugging time because such a mistake isn’t easy to find. The following code will show this disadvantage. Both lines of code are valid but the second one will result in runtime errors as you mixed up the parameters.

static void Main(string[] args)
{
  (double width, double height) = GetRectangle();

  (double height, double width) = GetRectangle();
}

 

Furthermore, you can get in trouble in case someone changes a class you are using. For example, several class properties get changed as result of a refactoring. So, their names and meanings will be changed. If you use this class within you code and access the class properties your compiler will show you according error messages as the property names have changed. But if you use deconstruction and the number and type of parameters haven’t changed you will get in trouble. Names and meanings of class elements have changed but the deconstruction method does only consider number and type of parameters. So, neither the compiler nor you will suspect any issues if you use the refactored class. But during runtime of your application you can expect some unpleasant surprises followed by hours of debugging and bug fixing.

Let’s look at the example with the rectangle. The developer of this class has done a refactoring and now the rectangle is represented as vector with an angle and a length. But unfortunately, the Deconstruction interface hasn’t changed and so you do not get any compilation errors.

static void Main(string[] args)
{
  (double width, double height) = GetRectangle();
}

private static Rectangle GetRectangle()
{
  return new Rectangle(5, 8);
}

class Rectangle
{
  public Rectangle(double vectorAngle, double vectorLength)
  {
    VectorAngle = vectorAngle;
    VectorLength = vectorLength;
  }

  public double VectorAngle { get; }
  public double VectorLength { get; }

  public void Deconstruct(out double vectorAngle, out double vectorLength)
  {
    vectorAngle = VectorAngle;
    vectorLength = VectorLength;
  }
}

 

In my opinion the deconstruction feature comes with more disadvantages then advantages. The advantage of a little bit shortened source code is way too small compared to the disadvantage of possible hard to find implementation Errors.

Werbung
Dieser Beitrag wurde unter C# veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Eine Antwort zu Deconstruction in C# 7

  1. Pingback: Tuples in C# 7 (ValueTuple) | coders corner

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit deinem WordPress.com-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s