How to make a properly make setter edit class members - c#

I am trying to make a setter for the public property of the private member age. It operates so that if the age you are trying to input is less than zero, the program should set it to zero and give you a basic message. However, this setter will literally let any negative number slip past it. If you try to edit it in the constructor, the setter doesn't even activate. But if you make an instance of the age class than try to edit that instances class, you can. However, it will let numbers less than zero pass through, and send the message "Viable", meaning it is a viable number. Here is the Person class the age member, property, constructor, etc. is located in.
namespace HopeThisWorks
{
class Person
{
private int age;
public int Age
{
get
{
return age;
}
set
{
if(age >= 0)
{
age = value;
System.Console.WriteLine("Viable");
}
else
{
age = 0;
System.Console.WriteLine("Not Viable");
}
}
}
public Person(int age)
{
this.age = age;
}
}
}
Here is the main method:
using System;
namespace HopeThisWorks
{
class Program
{
static void Main(string[] args)
{
Person p1 = new Person(1);
p1.Age = -1;
}
}
}
Any help would be muchly appreciated. Thank you!

Here's the working thing
using System;
public class Program
{
public static void Main()
{
var p = new Person(-5);
}
}
class Person
{
private int _age;
public int Age
{
get {return _age;}
set
{
if (value >= 0)
{
_age = value;
System.Console.WriteLine("Viable");
}
else
{
_age = 0;
System.Console.WriteLine("Not Viable");
}
}
}
public Person(int age)
{
Age = age;
}
}
In this case result will be Not Viable printed out.
Explanation is in Mark's comment.

Related

update referenced value of object/struct by <action>

i need help to IMPROVE my code.
The goal is to establish a technique to initialize and update values that get bound to of a winform control with one line of source code.
This code is used to initialize and also update the values of the winform controls.
The code is NOT the original but only to show the technique.
To me it is elegant because it is "one liner" code ( and also no need of reflection )
The critical part is the folowing code block (Update_Form)
the referenced/bound value that shall be changed e.g. person.Name has alwas to be written twice.
a. as Action ( value => person.Name = value ) to be stored in the winform control for the
eventHandler to set the BOUND variable when the value_changed event is raised.
b. as input to update the value of the winform variable beeing shown in the formular
It is not "so bad" but makes the code somewhat unreadable because in the orgininal the variable paths are much longer.
So i search for a good trick that avoids to write the referenced variable twice.
boun
public static void Update_Form(bool do_Init)
{
Person_Name_Updown.Update (handler, do_Init, value => person.Name = value, person.Name);
Person_Age_TextBox.Update (handler, do_Init, value => person.Age = value, person.Age);
Adress_Road_TextBox.Update (handler, do_Init, value => person.Adress.Road = value, person.Adress.Road);
Adress_Number_Updown.Update (handler, do_Init, value => person.Adress.Number = value, person.Adress.Number);
...
...
...
print_Status();
}
using System;
using System.Diagnostics;
public interface IOwnControl
{
void Upate_Value();
}
public static class Util
{
public static void SetString(string input, Action<string> setOutput)
{
if (!string.IsNullOrEmpty(input))
{
setOutput(input);
}
}
public static void SetInt(int input, Action<int> setOutput)
{
setOutput(input);
}
}
public struct Adress
{
public string Road ;
public int Number;
}
public class Person
{
public string Name ;
public int Age;
public Adress Adress ;
}
public class Updown_int : IOwnControl
{
public Action<int> Act_int;
public int Value;
public void Update(EventHandler a_handler, bool doInit, Action<int> a_Act_int, int a_Value)
{
if(doInit)
{
this.Act_int = a_Act_int;
this.ValueChanged += a_handler;
}
else
{
this.Value = a_Value;
}
}
public void Upate_Value()
{
Util.SetInt( this.Value, Act_int);
}
}
public class TextBox_string : IOwnControl
{
public Action<string> Act_string;
public string Value ;
public void Update(bool doInit, Action<string> a_Act_string, string a_Value)
{
if(doInit)
{
this.Act_string = a_Act_string;
}
else
{
this.Value = a_Value;
}
}
public void Upate_Value()
{
Util.SetString( this.Value, Act_string);
}
}
public class Program
{
static TextBox_string Person_Name_Updown = new TextBox_string();
static Updown_int Person_Age_TextBox = new Updown_int();
static TextBox_string Adress_Road_TextBox = new TextBox_string();
static Updown_int Adress_Number_Updown = new Updown_int();
static Person person = new Person();
public static void print_Status()
{
Console.WriteLine();
Console.WriteLine(person.Name);
Console.WriteLine(person.Age);
Console.WriteLine(person.Adress.Road);
Console.WriteLine(person.Adress.Number);
}
public static void Main()
{
Update_Form(true);
person.Name = "Herbert_Lena";
person.Age = 36;
person.Adress.Road = "Balfour Road";
person.Adress.Number = 34567;
Update_Form(false);
Person_Name_Updown.Value = "New name Hans";
Value_Changed(Person_Name_Updown);
Update_Form(false);
}
public static void Update_Form(bool do_Init)
{
Person_Name_Updown.Update (do_Init, value => person.Name = value, person.Name);
Person_Age_TextBox.Update (do_Init, value => person.Age = value, person.Age);
Adress_Road_TextBox.Update (do_Init, value => person.Adress.Road = value, person.Adress.Road);
Adress_Number_Updown.Update (do_Init, value => person.Adress.Number = value, person.Adress.Number);
print_Status();
}
public static void Value_Changed(IOwnControl a_Control)
{
a_Control.Upate_Value();
}
}

How do Setter and Getter methods work?

Before I started encapsulation and learn how to use properties, I was looking at Setters and Getters methods.
I understood how SetID and GetID methods works but I wasn't sure about SetName, GetName and GetPassMark methods.
using System;
public class Student
{
private int _id;
private string _Name;
private int _PassMark = 35;
public void SetId(int Id)
{
if (Id<=0)
{
throw new Exception("Student Id cannot be negative");
}
this._id = Id;
}
public int GetId()
{
return this._id;
}
public void SetName(string Name)
{
if(string.IsNullOrEmpty(Name))
{
throw new Exception("Name cannot be null or empty");
}
this._Name = Name;
}
public string GetName()
{
if(string.IsNullOrEmpty(this._Name))
{
return "No Name";
}
else
{
return this._Name;
}
}
public int GetPassMark()
{
return this._PassMark;
}
}
public class Program
{
public static void Main()
{
Student C1 = new Student();
C1.SetId(101);
C1.SetName("Mark");
Console.WriteLine("ID = {0}" , C1.GetId());
Console.WriteLine("Student Name = {0}", C1.GetName());
Console.WriteLine("PassMark = {0}", C1.GetPassMark());
}
}
When I looked at SetName, I understood that if the string is either empty or null, we throw exception and otherwise this._Name = Name.
But when I looked at GetName, I didn't really understand why there is the if statement.
If Name was null or empty, there wouldn't have been this._Name as we throw exception in SetName.
Can't we just write down return this._Name in GetName?
Also in GetPassMark method why is this. necessary in return this._PassMark?
Because _Name is not being set when you are creating the object. So there is a possibility that a Student object will have null _Name. You can fix it by setting the _Name in the constructor, then you can just return it.
Many people prefer to use this even when it's not really necessary since it makes the code more obvious. It's just a syntactical preference.

Infinite loop in getter/setter c# [duplicate]

This question already has answers here:
Overloading getter and setter causes a stack overflow in C# [duplicate]
(4 answers)
Closed 3 years ago.
class Program
{
static void Main(string[] args)
{
something s = new something();
s.DoIt(10);
Console.Write(s.testCount);
}
}
class something
{
public int testCount
{
get { return testCount; }
set { testCount = value + 13; }
}
public void DoIt(int val)
{
testCount = val;
}
}
Is what I have, because I was wanting to test and play around with the getters/setters stuff for C#. However, I get a StackOverFlowException was unhandled at "set { testCount = value + 13}". And I can't step through it, as I get a "The debugger cannot continue running the process. Process was terminated" message from Visual Studio. Any ideas what I'm doing wrong?
Edit: Today I've learned that I've done a pretty stupid derp. Given the multitudes of instant responses. Now I know better.
You have an infinite recursion, as you are referring to the property in the property.
You should use a backing field for this:
private int testCount;
public int TestCount
{
get { return testCount; }
set { testCount = value + 13; }
}
Note the property name TestCount (which also conforms to C# naming standard), as opposed to the field name testCount (lowercase t).
You should declare a variable to back the property:
class something
{
private int _testCount;
public int testCount
{
get { return _testCount; }
set { _testCount = value + 13; }
}
...
You have a circular reference in your property's getter. Try this:
class Something
{
private int _testCount;
public int TestCount
{
get { return _testCount; }
set { _testCount = value; }
}
public void DoIt(int val)
{
_testCount = val;
}
}
This:
public int testCount
{
get { return testCount; }
it returns itself, which causes it to execute itself.
Instead of return the own property in itself, store the intended value in another (preferably protected or private) variable. Then manipulate that variable both in the setter and in the getter.
class Program
{
static void Main(string[] args)
{
something s = new something();
s.DoIt(10);
Console.Write(s.testCount);
}
}
class something
{
private int _testCount;
public int testCount
{
// you are calling the property within the property which would be why you have a stack overflow.
get { return _testCount; }
set { _testCount = value + 13; }
}
public void DoIt(int val)
{
testCount = val;
}
}

C# Errors and Headache >.< (MonoDevelop version2.8.2 for Unity 3d)

Ok so I have a problem :/ first off Im using C#.. Next, in the section where you see
public int BaseValue()
{
get{return _basevalue;}
set{_basevalue value; }
}
I get 3 Errors
1) Unexpected symbol `{'
2)Unexpected symbol `{' in class, struct, or interface member declaration
and
3) Parsing Error
and frankly its pissing me off -_- so does anyone know what the problem may be?
public class BaseStats {
private int _basevalue; //base value of this stat
private int _buffvalue; //amount needed to buff the stat
private int _expToLevel; //amount needed to move to the next level
private float _LevelModifier; //the modifier applied to the exp needed to raise the skill
public BaseStats()
{
_basevalue = 0;
_buffvalue = 0;
_expToLevel = 100;
_LevelModifier = 1.1f;
}
//Basic Setters and Getters
public int BaseValue()
{
get{return _basevalue;}
set{_basevalue value; }
}
public int BuffValue()
{
get{return _buffvalue; }
set{_buffvalue value; }
}
public int ExpToLevel()
{
get{return _expToLevel; }
set{_expToLevel.value; }
}
public float LevelModifier()
{
get{return _levelModifier; }
set{_levelModifier.value; }
}
private int CalculateExpToLevel()
{
return (int)(_expToLevel * _levelModifier);
}
public void LevelUp()
{
_expToLevel = CalculateExpToLevel();
_baseValue++;
}
public int AdjustedValue()
{
return _baseValue + _buffValue;
}
}
Properties do not have parentheses. Eliminate the () and fix your setter on what you intend to be properties. Eliminate the get/set on what you intend to be methods.
// this is a property
public int Foo
{
get { return foo; }
set { foo = value; }
}
// this is a method
public decimal Bar()
{
// do something and return a decimal
}
And note, as of C# 3, if your property is a simple get/set operation, you can use auto-implemented properties and eliminate the explicit backing variable.
public int Foo { get; set; }

is inaccessible due to its protection level

I can't figure this out. The problem is that the distance, club, cleanclub, hole, scores and par all say inaccessible due to protection level and I don't know why because I thought I did everything right.
namespace homeworkchap8
{
public class Clubs
{
protected string club;
protected string distance;
protected string cleanclub;
protected string scores;
protected string par;
protected string hole;
public string myclub
{
get { return club; }
set {club = value; }
}
public string mydistance
{
get { return distance; }
set { distance = value; }
}
public string mycleanclub
{
get { return cleanclub; }
set { cleanclub = value; }
}
public string myscore
{
get { return scores; }
set { scores = value; }
}
public string parhole
{
get { return par; }
set { par = value; }
}
public string myhole
{
get { return hole; }
set { hole = value;}
}
}
}
this is the derived class:
namespace homeworkchap8
{
public class SteelClubs : Clubs, ISwingClub
{
public void SwingClub()
{
Console.WriteLine("You hit a " + myclub + " " + mydistance);
}
public void clean()
{
if (mycleanclub != "yes")
{
Console.WriteLine("your club is dirty");
}
else
{
Console.WriteLine("your club is clean");
}
}
public void score()
{
Console.WriteLine("you are on hole " + myhole + " and you scored a " +
myscore + " on a par " + parhole);
}
}
}
This is the interface:
namespace homeworkchap8
{
public interface ISwingClub
{
void SwingClub();
void clean();
void score();
}
}
here is the main code:
namespace homeworkchap8
{
class main
{
static void Main(string[] args)
{
SteelClubs myClub = new SteelClubs();
Console.WriteLine("How far to the hole?");
myClub.distance = Console.ReadLine();
Console.WriteLine("what club are you going to hit?");
myClub.club = Console.ReadLine();
myClub.SwingClub();
SteelClubs mycleanclub = new SteelClubs();
Console.WriteLine("\nDid you clean your club after?");
mycleanclub.cleanclub = Console.ReadLine();
mycleanclub.clean();
SteelClubs myScoreonHole = new SteelClubs();
Console.WriteLine("\nWhat hole are you on?");
myScoreonHole.hole = Console.ReadLine();
Console.WriteLine("What did you score on the hole?");
myScoreonHole.scores = Console.ReadLine();
Console.WriteLine("What is the par of the hole?");
myScoreonHole.par = Console.ReadLine();
myScoreonHole.score();
Console.ReadKey();
}
}
}
In your base class Clubs the following are declared protected
club;
distance;
cleanclub;
scores;
par;
hole;
which means these can only be accessed by the class itself or any class which derives from Clubs.
In your main code, you try to access these outside of the class itself. eg:
Console.WriteLine("How far to the hole?");
myClub.distance = Console.ReadLine();
You have (somewhat correctly) provided public accessors to these variables. eg:
public string mydistance
{
get
{
return distance;
}
set
{
distance = value;
}
}
which means your main code could be changed to
Console.WriteLine("How far to the hole?");
myClub.mydistance = Console.ReadLine();
Dan, it's just you're accessing the protected field instead of properties.
See for example this line in your Main(...):
myClub.distance = Console.ReadLine();
myClub.distance is the protected field, while you wanted to set the property mydistance.
I'm just giving you some hint, I'm not going to correct your code, since this is homework! ;)
myClub.distance = Console.ReadLine();
should be
myClub.mydistance = Console.ReadLine();
use your public properties that you have defined for others as well instead of the protected field members.
In your Main method, you're trying to access, for instance, club (which is protected), when you should be accessing myclub which is the public property that you created.
You organized class interface such that public members begin with "my". Therefore you must use only those members. Instead of
myScoreonHole.hole = Console.ReadLine();
you should write
myScoreonHole.myhole = Console.ReadLine();
It's because you cannot access protected member data through its class instance.
You should correct your code as follows:
namespace homeworkchap8
{
class main
{
static void Main(string[] args)
{
SteelClubs myClub = new SteelClubs();
Console.WriteLine("How far to the hole?");
myClub.mydistance = Console.ReadLine();
Console.WriteLine("what club are you going to hit?");
myClub.myclub = Console.ReadLine();
myClub.SwingClub();
SteelClubs mycleanclub = new SteelClubs();
Console.WriteLine("\nDid you clean your club after?");
mycleanclub.mycleanclub = Console.ReadLine();
mycleanclub.clean();
SteelClubs myScoreonHole = new SteelClubs();
Console.WriteLine("\nWhat hole are you on?");
myScoreonHole.myhole = Console.ReadLine();
Console.WriteLine("What did you score on the hole?");
myScoreonHole.myscore = Console.ReadLine();
Console.WriteLine("What is the par of the hole?");
myScoreonHole.parhole = Console.ReadLine();
myScoreonHole.score();
Console.ReadKey();
}
}
}
You need to use the public properties from Main, and not try to directly change the internal variables.
The reason being you cannot access protected member data through the instance of the class.
Reason why it is not allowed is explained in this blog.
Though it is irrelevant to the case at hand, for the benefit of the next person who arrives at this article through a search engine, if the default constructor of your base class is marked as private, derived classes will incur a CS0122 diagnostic.
Instead, you must promote the private method to protected.
The protected method remains inaccessible to consumers of the derived class unless said class overrides it with a new constructor.

Categories