Using accessors in C# stack overflow - c#

From http://msdn.microsoft.com/en-us/library/aa287786(v=vs.71).aspx
public string Name { get {
return name; } set {
name = value; } }
So why is it that when I set the value as so:
public int numHighAttacksHit
{
get { return numHighAttacksHit - handicapHighAttacks; }
set { numHighAttacksHit = value; }
}
this.numHighAttacksHit = 0;
It keeps circling around again and again setting value to numHighAttacksHit until I reach a stack overflow? This is within the same class, does that matter?
screenshot: http://gyazo.com/a49757753acfbb5b51aaef5be033c948.png

The property needs a field to reference, like this:
private int numHighAttacksHit;
public int NumHighAttacksHit // <-- note the pascal case
{
get { return numHighAttacksHit - handicapHighAttacks; }
set { numHighAttacksHit = value; }
}
this.NumHighAttacksHit = 0;

You are referencing the property inside of it's definition causing the stack overflow, unlike the example from MSDN.
try
private int numHighAttacksHit;
public int NumHighAttacksHit
{
get { return numHighAttacksHit - handicapHighAttacks; }
set { numHighAttacksHit = value; }
}

C# is case sensitive: Name and name are two different things, and in the MSDN article it has name defined as a private field:
private string name; // the name field
public string Name // the Name property
{
get
{
return name;
}
}
In your example, you don't have that private field, so numHighAttacksHit is going in a loop accessing itself.

You are returning the value of the property numHighAttacksHit within the property numHighAttacksHit itself--this creates a non-terminating recursion and is the source of your stack overflow.

Because in the second one, you are setting numHighAttacksHit again and again, and in the first one you are setting the value to name variable not to the property.

Related

C# getter and setter returns null when adding validation

I'm implementing getters and setters on my code but I'm having trouble with my getter and setter, it always returns null when using a code for validation in the setter, Here's my code:
private string _employeeId;
public string EmployeeId
{
get
{
return this._employeeId
}
set
{
if (!String.IsNullOrEmpty(this._employeeId))
{
this._employeeId = value;
}
else
{
throw new Exception("Employee ID is required");
}
}
}
and in my application, I assign the value of _employeeId by
creating an object of the class
Employees obj = new Employees();
obj.EmployeeId = txt_empId.Text;
The setter is trying to set the local variable but will never set it because IsNullOrEmpty(this._employeeId) returns true, preventing it from ever being set. Perhaps you meant to check IsNullOrEmpty on value??
In your code the variable _employeeId is empty, because you do not set a initial value for it. and in set method you are validation _employeeId variable, so this result always is null, then throw the Exception! i think you want to validation a value what is set method input value. So you must validation variable value, instead of variable _employeeId!
private string _employeeId;
public string EmployeeId
{
get
{
return this._employeeId
}
set
{
if (!String.IsNullOrEmpty(value))
{
this._employeeId = value;
}
else
{
throw new Exception("Employee ID is required");
}
}
}

Initialization with null-coalescing operator?

I may not have a good grasp of the ?? operator yet and ran into a design flaw I couldn't explain.
Compare the following two properties, the only difference being how there are initialized: the first explicitly initialized, while the second with the ?? operator (or am I doing it wrong here?).
If I run data init with both properties, the collection based on the first property comes up populated as expected, while the second one with the ?? operator never gets populated and comes up with 0 elements in the collection.
Surely something is wrong here in my assumption; what is the flaw here?
P.S. Please ignore the Set method which is to implement INotifyPropertyChanged in the base class and has no bearing on this issue (which is confined to the type of initialization).
// property version 1
private ObservableCollection<UserName> _userNameColl = new ObservableCollection<UserName>();
public ObservableCollection<UserName> UserNameColl
{
get { return _userNameColl; }
set { Set(ref _userNameColl, value); }
}
// property version 2
private ObservableCollection<UserName> _userNameColl;
public ObservableCollection<UserName> UserNameColl
{
get { return _userNameColl ?? new ObservableCollection<UserName>(); }
set { Set(ref _userNameColl, value); }
}
// a simple class for creating object collection
public class UserName
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
// a simple test populating the collection
for (int i = 0; i < 4; i++)
{
// silly data init just for test
UserNameColl.Add(new UserName()
{
Name = $"UserName No {i}",
Age = 20 + i,
Email = $"email{i}#local.lan"
});
}
The second one never initializes your field but always returns a new collection. Try this one instead:
public ObservableCollection<UserName> UserNameColl
{
get { return _userNameColl ?? (_userNameColl = new ObservableCollection<UserName>()); }
set { Set(ref _userNameColl, value); }
}

Homework find matching object in a list of objects and access properties of that object

I am trying to create a program that mimics an ATM. In my program, I need to check if the string that a user enters matches the Name property of any objects within a list of objects. If it does not match, then the account is automatically added with some other default values. If it does match, then I need to set the variables that are accessed on another form to the properties of that account object. Additionally, those properties will need to be updated from the other form, so that the object is kept current. I think that I can figure out how to update those properties, but I am having difficulty with trying to set the variables to the current account, more specifically, how to access the properties of the matching account. My class constructor is as follows:
class Account
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
private int acctNum = 0;
public int AcctNumber
{
get
{
return acctNum;
}
set
{
acctNum = value;
}
}
//initialize the CheckBalance value to 100.00
private decimal checkBalance = 100.00M;
public decimal CheckBalance
{
get
{
return checkBalance;
}
set
{
checkBalance = value;
}
}
public Account(string Name)
{
this.Name = Name;
}
private decimal saveBalance = 100.00M;
public decimal SaveBalance
{
get
{
return saveBalance;
}
set
{
saveBalance = value;
}
}
}
This works out just fine, as the only constructor that I need is the Name property, while the other properties are automatically set to a base value. The list and relevant code that I currently have are as follows:
//variable that will be used to check textbox1.Text
string stringToCheck;
//array of class Account
List<Account> accounts= new List<Account>();
public MainMenu()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//set value to user's input
stringToCheck = textBox1.Text;
//set a var that only returns a value if the .Name already exists
var matches = accounts.Where(p => p.Name == stringToCheck);
//check through each element of the array
if (!accounts.Any())
{
accounts.Add(new Account(stringToCheck));
}
else if (matches != null)
//set variables in another form. not sure if these are working
Variables1.selectedAccount = ;
//is this calling the CheckBalance of the instance?
Variables1.selectedCheckBalance = accounts[i].CheckBalance;
//same thing?
Variables1.selectedSaveBalance = accounts[i].SaveBalance;
//switch to form
AccountMenu acctMenu = new AccountMenu();
this.Hide();
acctMenu.Show();
}
In the above code, the "else if (matches != null)" is more of a filler, since I am not sure what to use. Of course, I also need to re-write the portion "if (!accounts.Any())" because once the list is populated with at least one object, this code will never occur again. So, really, I just need to know how to check for a matching account and how to access the properties of that account so that I can set the Variables1 properties to match. Thanks for any help!
If it works for your particular situation, var account = accounts.FirstOrDefault(p => p.Name == stringToCheck) will give you the first account in the collection that matches the expression or null if nothing exists.
check if account != null to ensure you do not get a null reference exception when trying to get property values.
Then, use account.CheckBalance to get the property value for that particular account.
I may not be fully understanding the question and cannot comment because I do not have a 50 reputation : (

How to use get and set for array element in C#?

I have the following class:
public class test
{
private int i;
public test(int in)
{
i = in;
}
public int testint;
{
get { return i; }
set { i = testint; }
}
}
And the following code:
test[] data = new test[3];
for(int j = 0; j < 3; j++)
{
data[i] = new test(0);
data[i].testint = int.Parse(Console.ReadLine());
}
Console.WriteLine(test[0].testint);
Console.WriteLine(test[1].testint);
Console.WriteLine(test[2].testint);
When I run this program and type in 1, 2, 3 as the input, the output is 0, 0, 0. I don't understand why the get or set seem to be not working. If I initialize the array elements with a value other than 0, the output will be that. The data[i].testint = int.Parse(Console.ReadLine()); seems to not be working. How would I go about doing something like that?
Change the set method to this:
public int testint
{
get { return i; }
set { i = value; }
}
You setter is incorrect. It should be:
set { i = value; }
You had:
set { i = testint; }
Which only triggers the getter, which gets from i, so in the end your setter was doing i = i .
In a setter, the value keyword contains the new candidate value for the property. value's type equals the property's. I say candidate value because you can validate it and choose to not apply it.
In your case, you were not applying the value.
Update
Also, when defining getters and setters, no semicolon should be used. Code, then, would look like this:
public int testint
{
get { return i; }
set { i = value; }
}
I see two errors in this code:
public int testint;
{
get { return i; }
set { i = testint; }
}
There should be no semicolon after testint at the top. Also, set needs to assign using value, like this:
public int testint
{
get { return i; }
set { i = value; }
}
Change your setter to say:
set { i = value; }
value corresponds to the value you send to set the variable.
Here's simple way.
public int TestInt {get; set;}

C# StackOverflowException

Problem: I am trying to update a List. If a certain item's ID already exists in the List, I want to add onto that item's quantity. If not, then I want to add another item to the list.
cart = (List<OrderItem>)Session["cart"];
for(int counter = cart.Count-1; counter >= 0; counter--)
{
if (cart[counter].productId == item.productId)
{
cart[counter].productQuantity += item.productQuantity;
}
else if (counter == 0)
{
cart.Add(item);
}
}
cart[counter] and item represent an instance(s) of a custom object of mine. Currently when I finally find a matching ID, everything APPEARS as though it should work, but I get a StackOverflowException thrown in my custom object class.
public int productQuantity
{
get
{
return _productQuantity;
}
set
{
productQuantity = value;
}
}
It gets thrown right at the open-bracket of the "set". Could somebody please tell me what the heck is wrong because I've been going at this for the past 2+ hours to no avail. Thank you in advance.
the problem is in your setter of the productQuantity
it should read:
set
{
_productQuantity= value;
}
edit (naming convention):
public class Vertex3d
{
//fields are all declared private, which is a good practice in general
private int _x;
//The properties are declared public, but could also be private, protected, or protected internal, as desired.
public int X
{
get { return _x; }
set { _x = value; }
}
}
Replace productQuantity = value; with _productQuantity = value; (you're recurring infinitely by calling the setter over and over)
Why not just use this instead?
public int productQuantity { get; set; }
But the flaw was in the _
public int productQuantity {
get {
return _productQuantity;
}
set {
_productQuantity = value;
}
}
cart = (List<OrderItem>)Session["cart"];
int index = cart.Find(OrderItem => OrderItem.productId == item.productId);
if(index == -1) {
cart.Add(item);
} else {
cart[index].productQuantity += item.productQuantity;
}
public int productQuantity
{
get
{
return _productQuantity;
}
set
{
_productQuantity = value; //this should be an assignment to a member variable.
}
}

Categories

Resources