I'm following a YouTube video and am wondering if there are any other efficient ways of doing this. Is it possible to do it with an interface too?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Learning
{
class Program
{
static void Main(string[] args)
{
Shape Rect = new Rectangle(5, 3);
Shape Tri = new Triangle(8, 12);
Rectangle CombinedRectangle = new Rectangle(3, 3) + new Rectangle(6, 6);
Console.WriteLine(CombinedRectangle.Area());
}

abstract class Shape
{
public abstract double Area();

}

class Triangle : Shape
{
private double theBase { get; set; }
private double theHeight { get; set; }

public Triangle(double theBase, double theHeight)
{
this.theBase = theBase;
this.theHeight = theHeight;
}

public override double Area()
{
return (theBase * theHeight) / 2;
}
}

class Rectangle : Shape
{
private double Length { get; set; }
private double Width { get; set; }

public Rectangle(double Length, double Width)
{
this.Length = Length;
this.Width = Width;
}

public override double Area()
{
return Length * Width;
}

public static Rectangle operator+ (Rectangle r1, Rectangle r2)
{
double combinedWidth = r1.Width + r2.Width;
double combinedLength = r1.Length + r2.Length;
return new Rectangle(combinedLength, combinedWidth);
}
}

}
}

• I'm a bit leery about that use of the + operator. Most people wouldn't think that a 1x1 rectangle "plus" a 2x2 rectangle makes a 3x3 rectangle. – Ben Aaronson Oct 12 '15 at 16:18

To answer your direct question, yes an interface would be better than an abstract class. Plus you may want to consider that Area could be a property rather than a method.

For the Triangle class, you may want to give simpler names to the base and height. So Base instead of theBase and Height instead of theHeight. And they should be public properties, perhaps with private setters.

public double Base { get; private set; }
public double Height { get; private set; }


For Rectangle class, the Length and Width could also be public.

public double Length { get; private set; }
public double Width { get; private set; }


Also the constructor should use lower casing for the arguments:

public Rectangle(double length, double width)


The operator could be shortened:

public static Rectangle operator+ (Rectangle r1, Rectangle r2)
{
return new Rectangle(r1.Length + r2.Length, r2.Width+ r2.Width);
}


Or if you are using C# 6.0:

public static Rectangle operator+ (Rectangle r1, Rectangle r2) => new Rectangle(r1.Length + r2.Length, r2.Width+ r2.Width);


The last line uses an Expression-bodied function member found in C# 6.0. A single line method body can be replaced with a 'lambda arrow' and you can omit the return since its implied.

Putting it altogether

Using C# version 6.0 syntax

interface IShape
{
double Area { get; }
}

public class Triangle: IShape
{
public double Base { get; private set; }
public double Height { get; private set; }
public Triangle(double theBase, double theHeight)
{
Base = theBase;
Height = theHeight;
}
public double Area => (Base * Height) / 2;
}

public class Rectangle : IShape
{
public double Length { get; private set; }
public double Width { get; private set; }
public Rectangle(double length, double width)
{
Length = length;
Width = width;
}
public double Area => Length * Width;

public static Rectangle operator+(Rectangle r1, Rectangle r2) => new Rectangle(r1.Length + r2.Length, r2.Width+ r2.Width);
}

• The signature in my example declares Area as a property rather than a method. Just like Base and Height are properties of a Triangle, and Length and Width are properties of a Rectangle, it makes more sense to me that any shape would have a property of Area. – Rick Davin Oct 11 '15 at 19:35