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?
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
or 2) a backing field
they both equate to the same code.
For an explanation, when you get
time
in your code:it has to retrieve the value of
time
to return. It does that by calling theget
ontime
, which has to get retrieve the value oftime
, etc.When you "get"
price
, the getter forprice
is called, which calls the getter forprice
, which calls the getter forprice
, which...Just use auto-implement properties if you don't want to mess with a backing field:
Some other observations:
The standard convention for property names is to start them with a capital letter, which is why I changed your properties to
Time
andPrice
in my examples.You may want to consider using
decimal
for a property likePrice
if you do any floating-point math, sincedouble
has some slight imprecision when representing decimal numbers like 1.1.decimal
will store the number exacly without any loss of precision.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.Properties getters and setters are really just
getXXX
andsetXXX
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.As stated by other answers, you can use backing fields or auto-implemented properties.