1

Below are the two different examples from the book Illustrated C# 2012. In the first example Hypotenuse is declared as readonly. In second example PI and numberofsides are declared as readonly. Why is PI assigned a value and numberofsides is not?

Can const be used to declare PI and assign a value to it? Let's say if I want to implement right triangle portion of class shape in second example. How do it do it with numberofsides are already declared and the sides have no values assigned. I mean how do I find out which side is hypotenuse?

class RightTriangle
{
   public double A = 3;
   public double B = 4;

   public double Hypotenuse // Read-only property
   {
      get{ return Math.Sqrt((A*A)+(B*B)); } // Calculate return value
   }
}

class Program
{
   static void Main()
   {
      RightTriangle c = new RightTriangle();
      Console.WriteLine("Hypotenuse: {0}", c.Hypotenuse);
   }
}

class Shape
{ 
    // Keyword Initialized
    // ↓↓
    readonly double PI = 3.1416;
    readonly int NumberOfSides;
    // ↑↑

    // Keyword Not initialized
    public Shape(double side1, double side2) // Constructor
    {

        // Shape is a rectangle
        NumberOfSides = 4;
        // ↑
        // ... Set in constructor
    }
    public Shape(double side1, double side2, double side3) // Constructor
    {
        // Shape is a triangle
        NumberOfSides = 3;
        // ↑
        // ... Set in constructor
    }
}
6
  • I just read through the code and realised the answer below doesn't address your problem. Are you sure the NumberOfSides property isn't initialised? Are you getting 0? Commented Mar 31, 2014 at 20:45
  • Yes I got 0 first time.
    – Rayhose
    Commented Mar 31, 2014 at 21:00
  • If it is possible can you give me an example or finish implementing the right triangle portion of the example on the last frame. If it is not too much to ask. I understand better if I can look at the examples.
    – Rayhose
    Commented Mar 31, 2014 at 21:04
  • @Rayhose I don't think you should be getting 0 here at all with the exact code you have provided for Shape. It should work as is. I've tested your code here. I get 4 as the output, which seems to be the expected behavior. Are you instantiating Shape using the right constructor? Commented Mar 31, 2014 at 21:54
  • Asad thank you. I got the point what you are trying to say. But still couldn't figure out if I have to use the value of PI to find the area of circle, how do I do it?
    – Rayhose
    Commented Apr 1, 2014 at 2:16

1 Answer 1

2

Constants are actually embedded into the metadata of your assembly. If someone references your constant, it too gets copied across to improve performance. The general rule is never use public constants for values that may change, so Math.PI is a constant. But not double.Zero. Constants can never be reference types, only value types.

Using a static readonly gets around this as it can be assigned at runtime, and therefore never stores the value in the same way. Sure you can pre-set it to a value, but the difference is external applications don't grab the value assigned and copy it.

The other difference is that a const cannot be assigned a value during runtime. A readonly can be changes, but only in the constructor. That is why properties cannot be marked with readonly, but can be coded to work like it is by having a public get, and a private readonly field.


To answer your question, I would mark PI as a constant, or use Math.PI. I'd also say the pattern you are attempting isnt flexible enough for what you want. Shape (2D?) should be an abstract class and have methods like GetArea, GetPerimeter, and properties like Length and Height. Then subclass the Shape into concrete shapes like RightAngleTriangle, Circle, Square. These subclasses can have their own constructors to initialise the specific ones.

Have a look at factory patterns for this, or inheritance constructs. This sort of pattern is a textbook example on it.

6
  • I neglected to cover this in my answer as well, but do you have any idea why the OP's snippet behaves as they claim it does? Commented Mar 31, 2014 at 20:50
  • I have very less idea about OP's behavior. I started C# 2 months ago. Try to study on my own, sometimes I don't get anything I read.
    – Rayhose
    Commented Mar 31, 2014 at 21:00
  • Did you mean something like this: { class Shape { int A; int B; public int AreaRect(int a, int b) { get { return a*b; } }
    – Rayhose
    Commented Mar 31, 2014 at 21:16
  • public int AreaTri(int a1, int b1, int c1) { get { return 1/2 * a1* b1; } } class Program { static void Main(string[] args) { Shape obj = new Shape(); int result = obj.AreaRect(3,5); Console.WriteLine("The area of the rectangle is {0}",result ); } } } }
    – Rayhose
    Commented Mar 31, 2014 at 21:18
  • I don't know what happen to the code. Why it all went in one paragraph. Sorry.
    – Rayhose
    Commented Mar 31, 2014 at 21:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.