1
namespace Area
{
    public class Rectangle
    {
        private double length;
        private double width;

    public Rectangle() { }

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

    public double Length
    {
        get
        {
            return length;
        }

        set
        {
            length = value;
        }
    }

    public double Width
    {
        get
        {
            return width;
        }

        set
        {
            width = value;
        }
    }

    public double getArea()
    {
        return width * length;
    }

    public double getPerimeter()
    {
        return 2 * width + 2 * length;
    }

    public double getDiagonal()
    {
        return Math.Sqrt(Math.Pow(width, 2) + Math.Pow(length, 2));
    }

I want to make sure I am using best practices with C# Objects. Please use the above example for reference.

1. Is it necessary that I type the first empty Constructor? In class the Instructor always did on each program but never really gave an answer as to why.

public Rectangle() { }

2. Inside my Custom Constructor Visual Studio generates it like this: this.Length = length;

I know that the "this" keyword is not necessary the way it is typed, but in class the instructor sometimes changed it to lowercase like this:

this.length = length;

But sometimes he didn't change it. Which way is best practices?

And is the left side the actual Property? And then the right side is the field?

So it is, Property equals field?

3. And finally, in this case cant I just type my properties as:

public string Length { get; set; }

instead of the way Visual Studio generates with the return and value.

Sorry for the long post, I am tired of getting different answers at school and want one final answer on this, thanks.

Programmer7
  • 159
  • 1
  • 4
  • 10
  • There's a chance that your instructor used to be a Java developer. In Java, if you wanted to use something as a Java Bean, it had to have a no argument constructor. – Powerlord Aug 23 '16 at 03:52
  • Thanks, so in C# I dont ever need to type empty Constructor myself? – Programmer7 Aug 23 '16 at 03:54
  • 1
    @Programmer7 The empty constructor is not necessary. But best practice does not dictate either way. If you want it, go for it. Also, neat trick in Visual Studio - in a new class, type "ctor", then hit the tab button twice. – onefootswill Aug 23 '16 at 03:55
  • Thanks, that takes care of #1 completely then. Now I just need info on #2 and #3. – Programmer7 Aug 23 '16 at 03:57
  • 1
    _"I dont ever need to type empty Constructor myself?"_ - There are cases where you do need it like when a class has a constructor with arguments and a default constructor, both with different behaviour. But yes, if you only use the default constructor in theory, then you may omit it –  Aug 23 '16 at 03:58
  • Thanks, I understand what you mean, I will use empty constructor only when needed. – Programmer7 Aug 23 '16 at 04:00
  • 2) FxCop would say that you should omit the `this`. Fxcop would also say that fields be prefixed with an underscore `_`. The whole `this` prefix is generally for those programmers who don't like `_`. Having fields the same name as arguments is perhaps a dangerous idea too. Other than that, naming conventions is a hot topic and is perhaps better discussed with your team to see what works for you –  Aug 23 '16 at 04:00
  • _"are you really saying Property equals Field?"_ - no. If your code was `this.length = length` then it could get confusing, `this.Length = length` is better, but `Length = length` is best. In your example you could omit the backing fields completely and just use properties –  Aug 23 '16 at 04:06
  • But what is Length = length? That was my question, when you type Length = length, are you saying Property equals Field? What is the reason for typing Length = length or Width = width, etc in a Custom Constructor? – Programmer7 Aug 23 '16 at 04:08
  • @Programmer7 I just wanted to address your question in a later comment about _are you really saying Property equals Field_. The answer to that is no. The length which comes from the parameter of the constructor is not in the same scope as the backing field called length. When you assign that to Length, that does, in turn, assign that value to the backing field by way of the Setter. So, the value does make it's way to the scope of the backing field. But in the Constructor, the parameter called _length_ hides the backing field called _length_. I name my fields with an underscore prefix as well. – onefootswill Aug 23 '16 at 05:39
  • Oh so in Length = length the lowercase length is actually the setter from the property Length? Also can you change my revised class from below to how you would do it? As you can see I was getting wrong info at school. Thanks – Programmer7 Aug 23 '16 at 13:21
  • @Programmer7 Your code is correct. I was just explaining that the _small l_ length in the body of the constructor is not the backing field. It is the value from the parameter of the constructor. When you assign it to the Length, the setter of the property sets the value of the backing field. So it comes in, via the constructor, and ends up assigned to the backing field. – onefootswill Aug 23 '16 at 21:37

3 Answers3

3

I would suggest that your class look like this:

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

    public double Length { get; set; }
    public double Width { get; set; }
    public double Area { get { return this.Width * this.Length; } }
    public double Perimeter { get { return 2.0 * (this.Width + this.Length); } }
    public double Diagonal { get { return Math.Sqrt(Math.Pow(this.Width, 2.0) + Math.Pow(this.Length, 2.0)); } }
}
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • Good idea on removing get from the method names. But why did you add get inside of the method? It looked like I didnt need to do that and was ok with starting method with return. – Programmer7 Aug 23 '16 at 13:17
  • They've made both Perimeter and Diagonal into properties (you can tell because there are no more parentheses). They've defined what get does, and omitted set, since the only way to set them should be through modifying width and length. – Kolichikov Aug 23 '16 at 20:33
  • @Programmer7 - I turned them from a method into a property. The `get` is a required part of a property. Have a read of this: https://msdn.microsoft.com/en-us/library/ms229054%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396 – Enigmativity Aug 23 '16 at 23:34
  • @Enigmativity Wow thanks, this is more great info that I can use. They dont teach you anything like this in school. – Programmer7 Aug 24 '16 at 20:44
  • 1
    @Programmer7 - You do tend to spend years and years learning what works and doesn't work, but there still tends to be quite a range of "best practices". You'll learn over time. – Enigmativity Aug 24 '16 at 23:57
0
  1. See here for why you might want a blank constructor. To summarize, adding a non blank constructor will stop the compiler from generating a blank one for you (the compiler assumes that if you wanted it, you would have defined it with the other constructors you wrote). Some things, like serialization, will not work without a blank constructor, so that's a reason you might want to add one.

  2. In my career, I've mostly seen people avoid using this in constructors. Maybe avoid isn't the right word, but unless it's unclear, they just didn't bother to put it there. This is probably too minor an issue to lose any sleep over.

UPDATE based on some of your comments

When you write

public Rectangle(double length, double width)
{
    Length = length; //parameter length assigned to field length by virtue of property Length
}

you are assigning the parameter length to the property Length, which itself assigns the passed in value to the length private field. Since C# is case sensitive, Length and length aren't confused in any scenario, and you don't need to specify the this keyword.

Inside a method with a parameter called length, the language is assuming that you are referring to the parameter of the method when you type length. So if you try to do something like this:

    public Rectangle(double length, double width)
    {
        length = length; //warning: Assignment made to same variable; did you mean to assign to something else
    }

The compiler doesn't try and assume that you are assigning the property to the field, and this is just assigning the length parameter to itself. In this case, you would use the this keyword to tell the compiler that you want to assign the parameter length to the private field length, like this:

    public Rectangle(double length, double width)
    {
        this.length = length; //no warning
    }

END UPDATE

  1. Yes, you could declare the property as just Property {get;set;}. This feature is only from C# 3.0 and is called auto-implemented properties (see this link). Before that you had to provide the implementation yourself.
Community
  • 1
  • 1
Kolichikov
  • 2,944
  • 31
  • 46
  • Right, "this" is only needed when they are identical including their case (all lowercase). But when you put Length = length inside of the Constructor, are you really saying Property equals Field? So should the first word be typed just like the Property is? – Programmer7 Aug 23 '16 at 04:04
  • Length = length and this.Length = length produce exactly the same result, in that they are assigning the parameter length to the private double length. Now, it's probably best practice to not name your private variables the same way you would name your parameters, because this code is confusing, but it's not illegal strictly speaking. In fact, in your example, the private fields aren't even necessary (public double Length {get;set} would suffice). – Kolichikov Aug 23 '16 at 04:10
  • Thanks , this helped a lot, looks like I was getting some bad info from class on naming the fields so closely like that. – Programmer7 Aug 23 '16 at 04:16
0

I changed my class to this:

public class Rectangle
    {
        public Rectangle(double length, double width)
        {
            Length = length;
            Width = width;
        }

        public double Length { get; set; }

        public double Width { get; set; }

        public double getArea()
        {
            return Width * Length;
        }

        public double getPerimeter()
        {
            return 2 * Width + 2 * Length;
        }

        public double getDiagonal()
        {
            return Math.Sqrt(Math.Pow(Width, 2) + Math.Pow(Length, 2));
        }
    }

If anyone has any other feedback on anything above that you recommend to change please give it, I catch on very fast and want to learn the correct way.

Programmer7
  • 159
  • 1
  • 4
  • 10
  • If I were you I would explicitly use `this.` to access all class properties. I would also change `getPerimeter` to a `get`-only property `Perimeter` (and the same for the rest of the `get*` methods). C# uses properties, Java uses `get*` methods. – Enigmativity Aug 23 '16 at 04:28
  • 1
    As per C# conventions method name should be in Pascal Case i.e. `GetArea`, `GetParameter`. – SiD Aug 23 '16 at 05:41
  • Thanks I will make sure to capitalize first letter of methods, again wrong info that I was provided by my instructor. Actually I will remove the word get from Method names. It appears instructor was pushing java way of doing things on c#. – Programmer7 Aug 23 '16 at 13:12