Why am I getting this StackOverFlowException - c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Test
{
private int myFaveNumber; //fields
private const int myLeastFaveNumber = 5;
private string secretPassword = "Pickle";
public int MyFaveNumber
{
get
{
return MyFaveNumber;
}
set
{
if (value > 0)
MyFaveNumber = value;
else
myFaveNumber = 10;
}
}
public int Math()
{
return myFaveNumber - myLeastFaveNumber;
}
public Test()
{
Console.WriteLine("Secret password is " + secretPassword);
}
public Test(string two)
{
Console.WriteLine("The full password is {0}", two);
}
}
class Program
{
static void Main(string[] args)
{
Test quick = new Test();
Console.WriteLine(quick.ToString());
quick.MyFaveNumber = 5;
Console.WriteLine(quick.Math());
Test quicky = new Test("Drill");
Console.ReadKey();
}
}
}
I am messing around as a beginner, and am wondering why I am getting a "Process is terminated due to StackOverflowException". If you could help me figure this out that would be great. Also any tips are always welcome.

It should be myFaveNumber not MyFaveNumber = value;
set
{
if (value > 0)
myFaveNumber = value;
else
myFaveNumber = 10;
}

The problem is in this part:
public int MyFaveNumber
{
get
{
return MyFaveNumber;
}
...
}
You've set the MyFaveNumber property to return itself. Likewise, in the setter:
set
{
if (value > 0)
MyFaveNumber = value;
else
myFaveNumber = 10;
}
You (conditionally) assign MyFaveNumber, causing the setter to call itself. Both of these scenarios will cause the property to recursively call its getter/setter over and over again until the program crashes.
You need to be getting/setting the private backing field myFaveNumber instead:
public int MyFaveNumber
{
get
{
return myFaveNumber;
}
set
{
if (value > 0)
myFaveNumber = value;
else
myFaveNumber = 10;
}
}

Consider property as a function.
When you write this functions
public int GetMyProperty()
{
return GetMyProperty();
}
public void SetMyProperty(int value)
{
if (value > 0)
SetMyProperty(value);
}
You will obviously recognize that there is possibility in infinite recursive call which will "blow up" your stack(default size of the stack for .NET applications is 1 MB). So you increase size of the stack with every recursive call which happened in you program when you execute.
quick.MyFaveNumber = 5;
And you will get same exception in case when you will try to read value of the property
Console.WriteLine(quick.MyFaveNumber);
So correct way of using properties assign values to the underlying private field when needed validation is done.
private int _myProperty;
public int MyProperty
{
}

Related

Get and Set condition value

I'm trying to learn get and set and I can't seem to figure out this problem. I have a condition to set a value, only set the value if it's greater than "_num = 10".
My problem is, even if the value is under 10 the value still sets. What am I missing? I should get an error with this code, but I'm not getting it...
thanks for ur time.
using System;
namespace Namespace
{
internal class Program
{
private static void Main(string[] args)
{
int x = Items.Sum = 5;
Console.WriteLine(x);
Console.ReadKey();
}
}
public static class Items
{
private static int _num = 10;
public static int Sum
{
get { return _num; }
set
{
if (value > _num)
_num = value;
}
}
}
}
Because your have property as static and it will be set even before the constructor gets called. That’s why it is returning 10.
Please declare the main method as public not private.

Converting vb to c# code

Could you help me here, this is my friend's work(actually don't know where did he get this code, it uses vb language) and i'm trying to convert the code to c#. Thought it was easy, even though i lack of c# knowledge, and i'm stacked from here. I found a vb.net to c# converter from the net, and this is the result:
*see the comment below
clsProcess.cs:
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
[Serializable()]
public class clsProcess : IComparable<clsProcess>
{
public int Priority
{
get { return _Priority; }
set { _Priority = value; }
}
public Color ProcessColor
{
get { return _ProcessColor; }
set { _ProcessColor = value; }
}
public double ArrTime
{
get { return _ArrTime; }
set { _ArrTime = value; }
}
public double ExeTime
{
get { return _ExeTime; }
set { _ExeTime = value; }
}
public string Label
{
get { return _Label; }
set { _Label = value; }
}
public clsProcess()
{
}
public clsProcess(int prior, double arr, double exe, string lbl, Color clr)
{
_Priority = prior;
_ArrTime = arr;
_ExeTime = exe;
_Label = lbl;
_ProcessColor = clr;
}
private double _ArrTime;
private double _ExeTime;
private string _Label;
private int _Priority;
private Color _ProcessColor;
public int CompareTo(clsProcess other)
{
switch ((modGlobals.SortColumn))
{
//The method SortType from modGlobals.cs is the error.
//Error says: The name 'SortType' does not exist in the current context
//I'm getting error from here:
case SortType.Arr:
return this.ArrTime.CompareTo(other.ArrTime);
case SortType.Exe:
return this.ExeTime.CompareTo(other.ExeTime);
case SortType.Label:
return this.Label.CompareTo(other.Label);
case SortType.Prior:
return this.Priority.CompareTo(other.Priority);
//Until here.
}
}
}
modGlobals.cs:
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
static class modGlobals
{
public enum SortType //The error referring to.
{
Arr,
Exe,
Prior,
Label
}
public static SortType SortColumn; //I doubt it has something to do here.
public static List<clsProcess> CreateMemberwiseClone(List<clsProcess> pList)
{
List<clsProcess> tempList = new List<clsProcess>();
int i = 0;
for (i = 0; i <= pList.Count - 1; i++) {
tempList.Add(CloneProcess(pList[i]));
}
return tempList;
}
public static clsProcess CloneProcess(clsProcess process)
{
clsProcess temp = new clsProcess();
temp.ExeTime = process.ExeTime;
temp.ArrTime = process.ArrTime;
temp.Label = process.Label;
temp.Priority = process.Priority;
temp.ProcessColor = process.ProcessColor;
return temp;
}
public static void MergeBlocks(ref List<clsBlock> blocks)
{
if (blocks.Count < 2)
return;
int i = 0;
while (i < blocks.Count - 1) {
if (blocks[i].BlockCaption == blocks[i + 1].BlockCaption) {
blocks[i].BlockLength += blocks[i + 1].BlockLength;
blocks.RemoveAt(i + 1);
i -= 1;
}
i += 1;
}
}
}
Could you give me an alternate solution for here?
try
public int CompareTo(clsProcess other)
{
switch ((modGlobals.SortColumn))
{
case modGlobals.SortType.Arr:
return this.ArrTime.CompareTo(other.ArrTime);
case modGlobals.SortType.Exe:
return this.ExeTime.CompareTo(other.ExeTime);
case modGlobals.SortType.Label:
return this.Label.CompareTo(other.Label);
case modGlobals.SortType.Prior:
return this.Priority.CompareTo(other.Priority);
}
//This next part will happen if the switch statement doesnt find a match
//use this to return some default value or a value that tells you it didnt find something
//I'll use 0 as an example
return 0;
//now all paths return a value, even if it doesnt find a match in the switch statement
}
Your static class modGlobals should only have static members.
The SortType should be static.
public static enum SortType
{
Arr,
Exe,
Prior,
Label
}

Why does using delegates in c# give a stackoverflowexception

When I came across delegates I wrote this really simple program just to practice. when I run it there is a stackoverflowexception. so if anyone can tell me what is wrong with this piece of code please do cause I have wasted a lot of time on trying to make it work but couldn't.
Here is the code:
using System;
public delegate void click();
class test
{
public click flare;
public double length;
public double Length
{
get
{
return Length;
}
set
{
Length = value;
flare();
}
}
}
class glance
{
public glance(ref test a)
{
a.flare = blank;
}
public void blank()
{
Console.WriteLine("this is blank");
}
}
class Program
{enter code here
static void Main(String[] args)
{
test know = new test();
glance x = new glance(ref know);
know.Length = 10;
}
}
It has nothing to do with delegates. You are calling setter method inside of setter in Lenght property and that causes the exception.Use the backing field you created for your property:
public double Length
{
get
{
return length;
}
set
{
length = value;
flare();
}
}

Make Length property available for my class C#

I want to create class Massive and to add a method for adding two massives. But property Length for my class instances doesn't work.
public static void Add(Massiv mas1, Massiv mas2, ref Massiv mas3)
{
if (mas1.Length != mas2.Length)
{
Console.WriteLine("Error!"); return;
}
for (int i = 0; i < mas.Length; ++i)
{
mas3[i] = mas1[i] + mas2[i];
}
}
How to make it available for my class?
It's my code.
class Massiv
{
public Massiv(int n)
{
mas = new int[n];
Random rand = new Random();
for (int i = 0; i < mas.Length; ++i)
{
mas[i] = rand.Next(0, 10);
}
}
public void ShowAll()
{
Console.WriteLine("Massive: ");
foreach (var elem in mas)
{
Console.Write(elem + " ");
}
Console.WriteLine();
}
public void ShowElement(int index)
{
try
{
Console.WriteLine("mas[{0}] = {1}", index, mas[index]);
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Error!");
}
}
public static void Add(Massiv mas1, Massiv mas2, ref Massiv mas3)
{
if (mas1.Length != mas2.Length)
{
Console.WriteLine("Error!"); return;
}
for (int i = 0; i < mas.Length; ++i)
{
mas3[i] = mas1[i] + mas2[i];
}
}
public int this[int index]
{
get { return mas[index]; }
set { mas[index] = value; }
}
private int[] mas;
}
}
It seems like you have not declared any Length property, therefore, the compiler cannot possibly know one.
Basically, add this to your class:
public int Length {
get {
}
set {
}
}
In the getter, you need to return the value of the property, while in the setter, you will have to change it.
In this case, you seem to want to retrieve the length of your internal array. If you do not need write-access, you can skip the set part:
public int Length {
get {
return mas.Length;
}
}
Just add this property to your class:
public int Length {
get { return mas.Length; }
}
Note it has only a get accessor, which makes it read only (You don't seem to need write access since you initialize the private array in the constructor).
public int Length {
get {
return mas.Length;
}
}

How can I access the variables in this method

I have a windows application that sends and receives messages to/from a microprocessor using the serial port.
The application is working fine and does what is supposed to do. Now, I need to make some elaboration with the data I receive back from serial and I would like to access the variable "value" in SetText method.
How can I access the content of that variable from another method or class?
Thanks for helping.
delegate void SetTextCallback(string text);
private void SetText(string text)
{
if (this.txtOutput.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.BeginInvoke(d, new object[] { text });
}
else
{
txtOutput.AppendText(text);
}
// capture messages from serial port
if (txtOutput.Text.Length > 0)
{
MatchCollection mc = Regex.Matches(txtOutput.Text, #"(\+|-)?\d+");
if (mc.Count > 0)
{
long value = long.Parse(mc[mc.Count - 1].Value);
if (value > 1 && value < 1000)
{
textBox2.Text = value.ToString();
}
else if (value < 2000 && value > 1000)
{
value = value - 1000;
textBox3.Text = value.ToString();
}
}
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
SetText(serialPort1.ReadExisting());
}
catch (Exception ex)
{
SetText(ex.ToString());
}
}
Consider this :
Make a property
public long Value { get; set; }
Use this in your code.
if (txtOutput.Text.Length > 0)
{
MatchCollection mc = Regex.Matches(txtOutput.Text, #"(\+|-)?\d+");
if (mc.Count > 0)
{
value = long.Parse(mc[mc.Count - 1].Value);
if (value > 1 && value < 1000)
{
textBox2.Text = value.ToString();
}
else if (value < 2000 && value > 1000)
{
value = value - 1000;
textBox3.Text = value.ToString();
}
}
If you want to make sure that this property retains its value then use static one.
public static long Value { get; set; }
If the data is going to be used more than one place then don't hesitate just create a class with the list of output variables that are to be shared among the methods. Create properties for that variables within that class. Now create an object for this class globally and assign the retrieved values from the microprocessor to the properties within this globally declared object. You can access this in any place. Because of this is a windows application the data will retain until you clear or the application was closed.
Here is the code. I have a textbox and two buttons in the windows app. One button to get the data and another to show the data. The data was get from the user using the textbox. After getting the data once on clicking the show data button it will show the data pushed to the object as many times you want.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
// Declare Global Variable
DataHolder objDataHolder = new DataHolder();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Here use your code to load the data retrieved from Microprocessor
objDataHolder.UserData = txtUserData.Text;
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show(objDataHolder.UserData);
}
}
// Class to hold Data
public class DataHolder
{
// Here have a list variables that you need to maintain that are retrieved from Microrocessor.
private string _userdata = string.Empty;
// Here have a list Properties that you need to maintain that are retrieved from Microrocessor.
public string UserData
{
get
{
return _userdata;
}
set
{
_userdata = value;
}
}
}
}
You can access the variable in other class using "Static" variable or instance variable
public class Demo1
{
//Static variable can be accessed without instantiating an instance of Demo1
public static int Number; //Demo1.Number
public string Info {get;set;}
}
public class AnotherClass
{
void DoSth()
{
Demo1.Number ++;
}
}
or if you have an instance of Demo1, say demo1Instance
demo1Instance.Info="Sth you like";
This is what I have done and it is now working.Thanks to all of you for the good suggestions. I am quite sure that I am going to use your examples very soon in the additional developments of the application.
internal long value;
private void SetText(string text)
{
if (this.txtOutput.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.BeginInvoke(d, new object[] { text });
}
else
{
txtOutput.AppendText(text);
}
// capture messages from serial port
if (txtOutput.Text.Length > 0)
{
MatchCollection mc = Regex.Matches(txtOutput.Text, #"(\+|-)?\d+");
if (mc.Count > 0)
{
value = long.Parse(mc[mc.Count - 1].Value);
if (value > 1 && value < 1000)
{
textBox2.Text = value.ToString();
}
else if (value < 2000 && value > 1000)
{
value = value - 1000;
textBox3.Text = value.ToString();
}
}
}
}

Categories

Resources