5

I have the following code:

namespace QuantStrats
{
    class Program
    {
        static void Main(string[] args)
        {
            string FilePath = "C:\\Users\\files\\DJ.csv";
            StreamReader streamReader = new StreamReader(FilePath);
            string line;
            List<Data> Data = new List<Data>();     

            while ((line = streamReader.ReadLine()) != null)
            {
                Data Tick = new Data();
                string [] values = line.Split(',');
                Tick.SetFields(values[1], values[2]);
                Data.Add(Tick);
            }

            for (int ii = 0; ii < Data.Count; ii++)
            {
                Data TickDataValues = new Data();
                TickDataValues = Data[ii];             
                Console.Write("TIME :" + TickDataValues.time + " Price : " + TickDataValues.price +  Environment.NewLine);
            }

            Console.ReadLine();
        }
    }

    class Data
    {
        public DateTime time
        {
            get { return this.time; }
            set
            {
                this.time = value;                
            }
        }

        public double price
        {
            get { return this.price; }
            set
            {
                this.price = value;                
            }
        }

        public void SetFields(string dateTimeValue, string PriceValue)
        {
            try
            {
                this.time = Convert.ToDateTime(dateTimeValue);
            }
            catch
            {
                Console.WriteLine("DateTimeFailed " + dateTimeValue + Environment.NewLine);
            }

            try
            {
                this.price = Convert.ToDouble(PriceValue);
            }
            catch
            {
                Console.WriteLine("PriceFailed " + PriceValue + Environment.NewLine);
            }
        }
    }
}

But I get a stack overflow exception.

I know it is because I am not doing my get and sets correctly and am entering an infinite loop, but I cannot see why exactly this is happening?

3 Answers 3

12
public DateTime time
{
    get { return this.time; }
    set
    {
        this.time = value;                
    }
}

you aren't using backing fields, but setting the property itself from within the property setter.

You can fix this by using 1) an auto property

public DateTime Time { get; set; }

or 2) a backing field

private DateTime _time;
public Datetime Time 
{
    get { return _time; }
    set { _time = value; }
} 

they both equate to the same code.

For an explanation, when you get time in your code:

get { return this.time; } 

it has to retrieve the value of time to return. It does that by calling the get on time, which has to get retrieve the value of time, etc.

Sign up to request clarification or add additional context in comments.

3 Comments

Backing fields, not backing properties.
yep thanks @JonSkeet, trying to be first and typing too quickly
Definitely a preference for #1 unless you need to do additional validation or other logic when setting/getting a property.
3

I cannot see why exactly this is happening?

    public double price
    {
        get { return this.price; }
        set
        {
            this.price = value;                
        }
    }

When you "get" price, the getter for price is called, which calls the getter for price, which calls the getter for price, which...

Just use auto-implement properties if you don't want to mess with a backing field:

    public DateTime Time {get; set;}
    public double Price {get; set;}

Some other observations:

  1. The standard convention for property names is to start them with a capital letter, which is why I changed your properties to Time and Price in my examples.

  2. You may want to consider using decimal for a property like Price if you do any floating-point math, since double has some slight imprecision when representing decimal numbers like 1.1. decimal will store the number exacly without any loss of precision.

  3. Just writing to the console in a catch block seems incorrect. You are basically ignoring the error (from a logic flow sense). Rather than accepting strings in the class and parsing them, I would do the validation in the calling code and making sure the inputs are valid before passing them to the class.

Comments

2

Properties getters and setters are really just getXXX and setXXX methods (that's how they are compiled). Because you set the property from the property itself, it is if you were recurring endlessly on a method.

public DateTime time()
{
    return time();
}

As stated by other answers, you can use backing fields or auto-implemented properties.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.