Funny response of field data with ++ operator C# - c#

I've got a program snippet here that allows the creation of an Employee object with simple properties of age, id, name and pay. Just playing around with it I noticed that
Console.WriteLine(joe.Age+1); is my Main() method returns one,
but Console.WriteLine(joe.Age++); returns 0. I know that the Age property, per the constructors is going to be initialized to 0, but why isn't 1 being added with the ++ operator? EDIT: I found the source of the strange behavior. In the Age property I have empAge=Age when it should've been equal to value
source:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EmployeeApp
{
class Employee
{
//field data
//notice the the fields are declared as private
//these fields are used in the constructors
private string empName;
private int empID;
private float currPay;
private int empAge;
//properties! private field data should be accessed via public properties
//note that properties don't use parentheses ()
//within the set scope you see the 'value' contextual keyword
//it represents the value being assigned by the caller and it will always be the same
//underlying data type as the property itself
public int Age
{
get { return empAge; }
set { empAge = Age; }
}
public string Name
{
get { return empName; }
set
{
if (value.Length > 15)
Console.WriteLine("this name is too long.");
else
empName = value;
}
}
public int ID
{
get { return empID; }
set { empID = value; }
}
public float pay
{
get { return currPay; }
set { currPay = value; }
}
//constructors
public Employee() { }
public Employee(string name, int id, float pay, int age)
{
empName = name;
empID = id;
currPay = pay;
empAge = age;
}
//methods
//the int parameter that this method takes will come from somewhere in the Main method
//currpay is a private field
public void GiveBonus(float amount)
{
currPay += amount;
}
public void DisplayStats()
{
Console.WriteLine("name: {0}", empName);
Console.WriteLine("ID: {0}", empID);
Console.WriteLine("pay: {0}", currPay);
Console.WriteLine("age: {0}", empAge);
}
}
}
Main method here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//Encapsulation using traditional accessors/mutators or get/set methods
//the role of a get method is to return to the caller the current value of the underlying state data
//a set method allows the caller ot change the current value of the state data
//you need to have a getter and a setter for every field that the class has
namespace EmployeeApp
{
class Program
{
static void Main(string[] args)
{
//Console.WriteLine("fun with encapsulation");
//Employee emp = new Employee("marvin", 456, 4000, 56);
//emp.GiveBonus(3);
// emp.DisplayStats();
// emp.Name = "wilson";
// emp.DisplayStats();
Employee joe = new Employee();
Console.WriteLine(joe.Age++);
}
}
}

The ++ incremental operator has two uses:
joe.Age++
and
++joe.Age
The first one, as you're using, is executed after the current operation. So, when you call Console.WriteLine(joe.Age++);, this can also be represented with:
Console.WriteLine(joe.Age);
joe.Age = joe.Age + 1;
So, you're passing the current value to WriteLine, and then incrementing it.
Leading with ++ will do the opposite - increment and then use the value. So, Console.WriteLine(++joe.Age); can also be read as:
joe.Age = joe.Age + 1;
Console.WriteLine(joe.Age);

When you use the unary ++ operator after the variable, the addition doesn't happen until after the outer expression is evaluated. When you use it before the variable, the addition happens before the outer expression is evaluated.
For instance,
// this will increment joe.Age, and then write it to console.
Console.WriteLine(++joe.Age);
versus
// this will write joe.Age to the console, and then increment it.
Console.WriteLine(joe.Age++);
From the docs on msdn:
The first form is a prefix increment operation. The result of the
operation is the value of the operand after it has been incremented.
The second form is a postfix increment operation. The result of the
operation is the value of the operand before it has been incremented.

In your Age property, you are not changing the empAge member to the value passed in. This is probably why you aren't seeing any changes when you tried ++ multiple times.
public int Age
{
get { return empAge; }
set { empAge = Age; } // this does not set the value!
}
Use the value instead:
public int Age
{
get { return empAge; }
set { empAge = value; } // use the value passed in
}
And as others have pointed out, you are using the postfix version of the ++ operator. The prefix version will increment the amount first before writing the property to the console.

In C++ and C#, there are two ++ operators. The first is a prefix operator (++age) and this one works as you are expecting -- increments the value and then returns the result. the postfix operator (age++) increments the value but returns the previous value.

Related

How to control the maximum value of variables?

As the title says, I would like to set the maximum value of the skill, stam and luck integers to the value of the related *Max integers. The *Max int values are set randomly during the start up of the program and the regular values are changed throughout the running of the program. There may be a few instances where the *Max value gets increased or decreased during play.
public static int skillMax = 0;
public static int stamMax = 0;
public static int luckMax = 0;
public static int skill = skillMax;
public static int stam = stamMax;
public static int luck = luckMax;
As my knowledge of C# is still in its infancy, I have not tried much. However I have searched far and wide on the internet however and not been able to find anything except for the MinValue and MaxValue fields and this piece of code with no explanation:
protected int m_cans;
public int Cans
{
get { return m_cans; }
set {
m_cans = Math.Min(value, 10);
}
}
Thanks in advance for any advice you throw my way!
Explanation for the code: Cans is a property. Properties provide controlled access to class or struct fields (variables). They consist of two methods called get to return a value and set to assign the value. A property can also have only a getter or only a setter.
The property Cans stores its value in a so called backing field. Here m_cans. The setter gets the new value through the keyword value.
Math.Min(value, 10) returns the minimum of the two parameters. I.e., for example, if value is 8, then 8 is assigned to m_cans. If value is 12, then 10 is assigned to m_cans.
You can use this property like this
var obj = new MyCalss(); // Replace by your real class or struct name.
obj.Cans = 20; // Calls the setter with `value` = 20.
int x = obj.Cans; // Calls the getter and returns 10;
Properties help to implement the principle of Information hiding.
You can easily adapt this example your variables. Often class level variables (fields) are prepended with _ to differentiate them from local variables, i.e. variables declared in methods. Properties are written in PascalCase.
private static int _skillMax; // Fields are automatically initialized to the default
// value of their type. For `int` this is `0`.
public static int SkillMax
{
get { return _skillMax; }
set {
_skillMax = value;
_skill = _skillMax; // Automatically initializes the initial value of Skill.
// At program start up you only need to set `SkillMax`.
}
}
private static int _skill;
public static int Skill
{
get { return _skill; }
set { _skill = Math.Min(value, _skillMax); }
}
Create methods to update values
private static void UpdateSkill(int newValue)
{
skill = newValue;
skillMax = newValue > skillMax ? newValue : skillMax;
}

Setting the value of a read only property in C#

I'm trying to make a mod for a game in c# and I'm wondering if there's a way to change the value of a read only property using reflections.
In general, no.
Three examples:
public int Value { get { return _value + 3; } } // No
public int Value { get { return 3; } } // No
public int Value { get; private set; } // Yes
So, you can change the value of the property while this property has corresponding private, protected or internal field.
Try this:
typeof(foo).GetField("bar", BindingFlags.Instance|BindingFlags.NonPublic).SetValue(foo,yourValue)
You can in both those scenarios:
readonly int value = 4;
and
int value {get; private set}
using
typeof(Foo)
.GetField("value", BindingFlags.Instance)
.SetValue(foo, 1000); // (the_object_you_want_to_modify, the_value_you_want_to_assign_to_it)
You cannot modify
int value { get { return 4; } }
though.
If it returns a calculated value like
int value { get { return _private_val + 10; } }
you would have to modify _private_val accordingly.
Yes, this is absolutely possible. Whether it is good practice or helpful to your purpose, I do not know. Going off of #ske57's great advice, here is a sample program that demonstrates reflection. The initial field value of 5 and the reflected field value of 75 are written to the console.
using System;
using System.Reflection;
namespace JazzyNamespace
{
class Program
{
static void Main()
{
var reflectionExample = new ReflectionExample();
// access the compiled value of our field
var initialValue = reflectionExample.fieldToTest;
// use reflection to access the readonly field
var field = typeof(ReflectionExample).GetField("fieldToTest", BindingFlags.Public | BindingFlags.Instance);
// set the field to a new value during
field.SetValue(reflectionExample, 75);
var reflectedValue = reflectionExample.fieldToTest;
// demonstrate the change
Console.WriteLine("The complied value is {0}", initialValue);
Console.WriteLine("The value changed is {0}", reflectedValue);
Console.ReadLine();
}
}
class ReflectionExample
{
public readonly int fieldToTest;
public ReflectionExample()
{
fieldToTest = 5;
}
}
}
As Mark said there could be scenarios where you cannot as . Think that the property itself could be a function derived from other properties, members.
However you may want to try the mechanisms explained here:
Is it possible to set private property via reflection?

Error CS1014: A get or set accessor expected

using System;
//Find the square root of a number for 10 values from user
class forLoop
{
static void Main
{
double x;
for(int i=10; i>0 && x>=0; i--)
{
Console.WriteLine("You have {0} remaining calculations left", i);
Console.Write("Please enter a positive number: ");
x = double.Parse((Console.ReadLine());
x = Math.Sqrt(x);
Console.WriteLine("The square root is {0}", x);
Console.WriteLine("");
}
Console.WriteLine("You have 0 remaining calculations left");
}
}
I need help on this C# problem: Why does the error: "A get or set accessor expected" come up at compile time?
You missed the () in method declaration. Thus, the compiler thinks at some level that you're declaring a Property (albeit it would then throw an error about the void type), not a Method
// Property
public int Property
{
get { return _field; }
set { _field = value; }
}
// Property, albeit a get-only property
public int Property => _field;
// Method
public int Method()
{
return _field;
}
// Method
public int Method() => _field;
UPDATE: Since this is still being seen, I've updated the example values to better reflect their underlying types, and included examples of expression bodies introduced with C# 6
You need parentheses (()) in the method declaration.
Parentheses is required to differentiate a method from a property that requires the get/set syntax

I am Totally lost Using Derived Classes in C# Visual 2010

This Is my Assignment, I am having Troubles Getting my Class To Work With main for, Can Someone please Help Me, This is due on Tuesday and I have been hitting a brick wall in every approach I have tried. all my class and my forms are posted. Please Help me I am totally lost and frustrated
1.Employee and ProductionWorker Classes
Create an Employee class that has properties for the following data:
•Employee name
•Employee number
Next, create a class named ProductionWorker that is derived from the Employee class.
The ProductionWorker class should have properties to hold the following data:
•Shift number ( an integer, such as 1, 2, or 3)
•Hourly pay rate The workday is divided into two shifts: day and night.
The Shift property will hold an integer value representing the shift that the employee works. The day shift is shift 1 and the night shift is shift 2.
Create an application that creates an object of the ProductionWorker class and lets the user enter data for each of the object’s properties. Retrieve the object’s properties and display their values.
This Is My Employee Reference Chart. To Store Their Names And I.D Numbers I am getting no compiling errors on this class, however I am not sure if I am doing this correctly because in my main I get a compiling error.
I assume I need an array to store all the data that will be inputted into my TextBox in visual
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Employee_References
{
class Roster
{
// Field for name, ID, dept, and position
private const int NAMES = 100;
private static string [] employee = new string [NAMES];
private const int NUMBER = 100;
private static int [] id = new int [NUMBER];
private int total = 0;
public void Employee()
{
total = 0;
}
// This will recieve input from my main
public static void employeeName (string [] xArray)
{
for (int index = 0; index < xArray.Length; index++)
{
xArray[index] = employee[NAMES];
}
}
// This will recieve input from my main
public static void idNumber ( int [] zArray)
{
for (int index = 0; index < zArray.Length; index++)
{
zArray[index] = id[NUMBER];
}
}
}
}
This will be my next class that is derived from my first class as my assignment requested. This class is suppose to store the shift numbers 1 through for 4, and an hourly wage setter for a Day and Night Shift. I am getting one compiling error in this class that says " The left-hand side of an assignment must be a variable, property or indexer" I am not sure What it is telling me, can someone please explain what it is trying to tell me. Am I doing this correctly?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Employee_References
{
class References : Roster
{
// Field for name, ID, dept, and position
private int shift;
private static const double PAYRATEDAY = 12.75;
private static const double PAYRATENIGHT = 15.75;
public void Employee()
{
}
// This will recieve input from my main
public int shifts
{
set {shift = value;} // this set the recieve value of name one and set it to name1
get {return shift; } //this will get name1 and send it to my main.
}
// This will recieve input from my main
public double payrate1
{
set { PAYRATEDAY = value; } // ERROR!!The left-hand side of an assignment must be a variable, property or indexer
get { return PAYRATEDAY; }
}
// This will recieve input from my main
public double payrate2
{
get { return PAYRATENIGHT; } // ERROR!!The left-hand side of an assignment must be a variable, property or indexer
set { PAYRATENIGHT = value; }
}
}
This is my Form, I am trying to send my input values into my class my "Roster" class That has an array of 100. How ever I keep getting a compiling error that says " Cannot assign to 'employeeName' because it is a 'method group". I am not sure What It is telling me can some one explain this to me, and give me some pointer on how to do this
using System;
using System.Windows.Forms;
namespace Employee_References
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Roster Chart = new Roster();
Chart.employeeName = name.Text; // Error **Cannot assign to 'employeeName' because it is a 'method group**".
}
}
}
employeeName() is a method and you are trying to assign it a value.
Looks like you want to try and pass an array of names to it as a parameter
//first define and populate myArray
Chart.employeeName(myArray)
You say
private static const double PAYRATEDAY = 12.75;
Then
public double payrate1
{
set { PAYRATEDAY = value; } // ERROR!!The left-hand side of an assignment must be a variable, property or indexer
get { return PAYRATEDAY; }
}
Why do you declare the field constant if you are changing it?
Also, I think you'd be better off using lists instead of arrays, so that it can grow dynamically as much as it needs instead of being limited by a fix number.

Shorthand Accessors and Mutators

I am learning C#, and am learning about making fields private to the class, and using Getters and Setters to expose Methods instead of field values.
Are the get; set; in Method 1 and Method 2 equivalent? e.g. is one a shorthand of the other?
class Student
{
// Instance fields
private string name;
private int mark;
// Method 1
public string Name { get; set; }
// Method 2
public int Mark
{
get { return mark; }
set { mark = value; }
}
}
Finally, would Method 2 be used when you want to for example perform a calculation before getting or setting a value? e.g. converting value to a percentage or perform validation? e.g.
class Student
{
// Instance fields
private string name;
private double mark;
private int maxMark = 50;
// Method 1
public string Name { get; set; }
// Method 2
public double Mark
{
get { return mark; }
set { if ( mark <= maxMark ) mark = value / maxMark * 100; }
}
}
Yes, the Method2 is the way to go when you have a custom getter and setter function. By default when you use Method1, there will be a default private property handled internally. Please refer this URL for more details.
Sample:
string _name;
public string Name
{
get => _name;
set => _name = value;
}
Yes, Method 1 is a shortcut to Method 2. I suggest using Method 1 by default. When you need more functionality, use Method 2. You can also specify different access modifiers for get and set.

Categories

Resources