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
Related
from this reference : http://functionalprogrammingcsharp.com/honest-functions
I have learned to be more honest when defining method/function in C#.
It said that prefer pure function so that the function will always give the exact return type given in signature.
However when I try to apply it:
int Divide(int x, int y)
{
return x / y;
}
From the website:
The signature states that the function accepts two integers and returns another integer. But this is not the case in all scenarios. What happens if we invoke the function like Divide(1, 0)? The function implementation doesn't abide by its signature, throwing DivideByZero exception. That means this function is also "dishonest". How can we make this function an honest one? We can change the type of the y parameter (NonZeroInteger is a custom type which can contain any integer except zero):
int Divide(int x, NonZeroInteger y)
{
return x / y.Value;
}
I'm not sure what is the implementation of NonZeroInteger, they don't seem to give any implementation of NonZeroInteger in the website, should it check for 0 inside that class? And
I'm pretty sure if I call Divide(1, null) it will still show an error, thus making the function not honest.
Why honest function example in C# still not being honest?
Taking the example you've posted, and having read the link, if you want to make the function "honest" then you don't really need to create a new type, you could just implement the Try pattern:
bool TryDivide(int x, int y, out int result)
{
if(y != 0)
{
result = x / y;
return true;
}
result = 0;
return false;
}
This function basically fulfills the "honest" principle. The name says it will try to do division, and the resulting 'bool` says that it will indicate it is was successful.
You could create a struct NonZeroInteger but you're going to have to write a lot of code around it to make it act like a regular numeric type, and you'll probably come full circle. For example, what if you pass 0 to the NonZeroInteger constructor? Should it fail? Is that honest.
Also, struct type always have a default constructor, so if you're wrapping an int it's going to be awkward to avoid it being set to 0.
To make it honest, define a new data structure and check the status.
enum Status { OK, NAN }
class Data
{
public int Value { get; set; }
public Status Status { get; set; }
public static Data operator /(Data l, Data r)
{
if (r.Value == 0)
{
// Value can be set to any number, here I choose 0.
return new Data { Value = 0, Status = Status.NAN };
}
return new Data { Value = l.Value / r.Value, Status = Status.OK };
}
public override string ToString()
{
return $"Value: {Value}, Status: {Enum.GetName(Status.GetType(), Status)}";
}
}
class Test
{
static Data Divide(Data left, Data right)
{
return left / right;
}
static void Main()
{
Data left = new Data { Value = 1 };
Data right = new Data { Value = 0 };
Data output = Divide(left, right);
Console.WriteLine(output);
}
}
The notion of "honest function" still has room for interpretation, and I don't want to debate about it here, would be more opinion than actual useful answer.
To specifically answer your example, you could declare NonZeroInteger as a ValueType, with struct instead of class.
A value type is non-nullable (except if you explicitly specify the nullable version with a ?). No null-problem in this case. By the way, int is an example of value type (it's an alias for System.Int32, to be exact).
As some have pointed out, it could lead to other difficulties (struct has always a default constructor that initialize all fields to their default, and the default for an int is 0...)
For an mid-experienced programmer, this kind of example does not need to be explicitly implemented in the article to be understood on principle.
However, if you are unsure about it, it would definitely be a good programming learning exercise, I strongly encourage you to implement it yourself! (And create unit tests to demonstrate that your function has no "bug", by the way)
This NonZeroInteger is just a "symbol", which just represents the idea, not conrete implementation.
Surely, author could provide implemenetation of such construct, but its name servers just right for the sake of an article.
Possible implememntation might be:
public class NonZeroInteger
{
public int Value { get; set; }
public NonZeroInteger(int value)
{
if( value == 0 ) throw new ArgumentException("Argument passed is zero!");
Value = value;
}
}
But it's just pushing dishonesty somewhere else (in terms of an article), because constructor should return an object, not throw exception.
IMO, honesty is not achievable, because it's just moving dishonesty somewhere else, as shown in this example.
After reading it thoroughly a lot of times..
I found that his second option on the website is honest, and the first one is wrong.
int? Divide(int x, int y)
{
if (y == 0)
return null;
return x / y;
}
Edit: got idea from another article, basically mimicking the F# path, something like this:
Option<int> Divide(int x, int y)
{
if (y == 0)
return Option<int>.CreateEmpty();
return Option<int>.Create(x / y);
}
public class Option<T> : IEnumerable<T>
{
private readonly T[] _data;
private Option(T[] data)
{
_data = data;
}
public static Option<T> Create(T element)
{
return new Option<T>(new T[] { element });
}
public static Option<T> CreateEmpty()
{
return new Option<T>(new T[0]);
}
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>) _data).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Match(Action<T> onSuccess, Action onError) {
if(_data.Length == 0) {
onError();
} else {
onSuccess(_data[0]);
}
}
}
Ref: https://www.matheus.ro/2017/09/26/design-patterns-and-practices-in-net-option-functional-type-in-csharp/
to call:
public void Main() {
Option<int> result = Divide(1,0);
result.Match(
x => Console.Log(x),
() => Console.Log("divided by zero")
)
}
I just want to mention that NonZeroInteger can definitely be implemented honestly using a variation on Peano numbers:
class NonZeroInteger
{
/// <summary>
/// Creates a non-zero integer with the given value.
/// (This is private, so you don't have to worry about
/// anyone passing in 0.)
/// </summary>
private NonZeroInteger(int value)
{
_value = value;
}
/// <summary>
/// Value of this instance as plain integer.
/// </summary>
public int Value
{
get { return _value; }
}
private readonly int _value;
public static NonZeroInteger PositiveOne = new NonZeroInteger(1);
public static NonZeroInteger NegativeOne = new NonZeroInteger(-1);
/// <summary>
/// Answers a new non-zero integer with a magnitude that is
/// one greater than this instance.
/// </summary>
public NonZeroInteger Increment()
{
var newValue = _value > 0
? _value + 1 // positive number gets more positive
: _value - 1; // negative number gets more negative
return new NonZeroInteger(newValue); // can never be 0
}
}
The only tricky part is that I've defined Increment so that it works with both positive and negative integers. You can create any integer value you want except zero, and no exceptions are ever thrown, so this class is totally honest. (I'm ignoring overflow for now, but I don't think it would be a problem.)
Yes, it requires you to increment by one repeatedly to build large integers, which is extremely inefficient, but that's OK for a toy class like this one. There are probably other honest implementations that would be more efficient (e.g. using a uint as an offset from +1 or -1), but I'll leave that as an exercise for the reader.
You can test it like this:
class Test
{
static int Divide(int x, NonZeroInteger y)
{
return x / y.Value;
}
static void Main()
{
var posThree = NonZeroInteger.PositiveOne
.Increment()
.Increment();
Console.WriteLine(Divide(7, posThree));
var negThree = NonZeroInteger.NegativeOne
.Increment()
.Increment();
Console.WriteLine(Divide(7, negThree));
}
}
Output is:
2
-2
Honestly this is, IMO, overkill, but if I were to do a "Honest" method. I would do something like this. Instead of creating an entire new class. This is not a recommendation of what to do, and could easily cause issues in your code later. The best way to handle this, IMO, is to use the function and catch the exception outside of the Method. This is an "Honest" method in the fact that it always returns an integer, but it could return false values back.
int Divide(int x, int y)
{
try
{
return x / y;
}
catch (DivideByZeroException)
{
return 0;
}
}
Read only properties can be assigned in a constructor. But when I try to explicitly implement get method, compiler shows an error (Property cannot be assigned to -- it is read only.) Can I implement getter or it's supposed to be without implementation?
public class PersonalIncome
{
private decimal _anualRate;
public decimal AnualRate
{
get { return _anualRate != 0 ? _anualRate : 40_000; }
}
public PersonalIncome(decimal paymentRate)
{
switch (paymentRate)
{
case var rate when (rate > 300):
AnualRate = rate; // **Property can not be assigned to -- it is read only.**
break;
default:
break;
}
}
}
You can implement the getter, but then you can only assign values to the backing field directly:
_anualRate = rate;
Once you decide against using the convenience of the auto-property, you have to do everything by yourself.
Your class could be rewritten like this:
public class PersonalIncome
{
public decimal AnualRate { get; private set; }
public PersonalIncome(decimal paymentRate)
{
AnualRate = paymentRate > 300 ? paymentRate : 40_000;
}
}
You refer to a property with a readonly backing-field.
That´s exactly what the compiler also generates from C#6 upwards when using an auto-implemented property with a default-value:
int MyProperty { get; } = -1;
This will be translated to the following:
readonly int _myProperty = -1;
int MyProperty { get { return this._myProperty; } }
Now the compiler replaces every call to your property by the backing-field. However this only works for auto-properties that do not have a body defined. In your case you already have one, which is why the compiler can´t replace that one. As a property itself is nothing but a get- and a set-method, what you want to do is the following, which is obvious non-sense:
int get_MyProperty() { return this._MyProperty; }
...
this.get_MyProperty() = 1;
The reason this works for an auto-property is that the compiler knows how to replace the call to the property. However suppose your own getter was more complex:
get
{
DoSomething();
return this._myProperty + 5;
}
Now the compiler can´t replace the call to the property.
So the only way to have your own get-implementation tigether with a property which is get-only, is to use the backing-field:
this._myProperty = 1;
I have a struct and an integer variable on it. My variable value must be between 1200 and 1599. but in default constructor I have no control in value of variable. How can I do this in my struct?
struct MyStruct
{
public int x;
public MyStruct(int x)
{
if(x>1599)
this.x=1599;
else if(x<1200)
this.x=1200;
else
this.x=x;
}
}
Another variant on using a property and a private backing field:
struct MyStruct
{
private int x;
public MyStruct(int x)
{
if (x > 1599)
this.x = 399;
else if (x < 1200)
this.x = 0;
else
this.x = x - 1200;
}
public int X { get { return x+1200; } }
}
Which ensures that the default constructed value is "in range".
But any variant is going to introduce some overhead, so it's up to you whether this is acceptable.
Use a property with a backing field:
struct MyStruct
{
private const int MIN_VALUE = 1200;
private const int MAX_VALUE = 1599;
private int x;
public int X
{
get { return x + MIN_VALUE; }
set
{
if(value > MAX_VALUE)
x = MAX_VALUE;
else if(value < MIN_VALUE)
x = MIN_VALUE;
else
x = value;
x -= MIN_VALUE;
}
}
// constructor is not really needed anymore, but can still be added
}
I combined the property with my setter and Damien_The_Unbeliever's getter to get the initial state of x right. I also agree with Tim about constants for the "magic numbers" and added that too. So please give this two also credit for "my answer".
Also as DatVM already said: Public fields/properties should start with a capital letter according to the common C# naming guidlines. This also enalbes you to use the same name for the backing field, but starting with a small letter (I personally do NOT like the ugly _)...
And last but not least: Please read rexcfnghk's answer, even if it is not really an answer, as he is also absolutely correct.
My variable value must be between 1200 and 1599
In C#, you cannot define your own default constructor for structs. If you have an array of MyStruct, like var myArray = new MyStruct[5], the default constructor of MyStruct will be invoked and elements in myArray will have all have x equals to 0, which is invalid according to your requirement.
Which is why I believe you have an incorrectly designed struct. According to the Framework Design Guidelines
√ DO ensure that a state where all instance data is set to zero, false, or null (as appropriate) is valid.
This prevents accidental creation of invalid instances when an array of the structs is created.
If you need argument validation when your struct's default constructor is invoked, use a class instead.
Also, your current design of MyStruct makes it mutable. please take a look on why Mutable structs are evil.
I would use properties with getter and setter and a private backing field where you can implement this logic or even throw an ArgumentOutOfRangeException if the value is outside of the boundaries.
Here is an example:
struct MyStruct
{
private const int MIN_VALUE = 1200;
private const int MAX_VALUE = 1599;
private int _X;
public int X
{
get { return _X; }
set { _X = checkBoundaries(value); }
}
private static int checkBoundaries(int x)
{
if (x > MAX_VALUE)
return MAX_VALUE;
else if (x < MIN_VALUE)
return MIN_VALUE;
else
return x;
}
public MyStruct(int x)
{
_X = checkBoundaries(x);
}
}
It's good practices to always use properties even if you don't need to restrict the access in the first place. Then it's easier to implement such a logic if you need.
One final note: i would suggest to use a class instead of struct.
You cannot define a default constructor in a struct, so you cannot prevent _X from being initialized with the default value 0.
You cannot initialze _X with the minimum value inline since that is also not allowed in structs
If your types are getting more comlex and you have rules like this it's a good indicator that a class would be more appropriate
You should change x into property instead:
private int _x;
public int x {
get
{
return _x;
}
set
{
_x = value;
if (_x > 1599)
{
_x = 1599
}
else if (_x < 1200)
{
_x = 1200
}
}
}
P.S: as for C# naming convention, it should be called X (capital) instead of x
A struct can be made to have a default value if, rather than using a public field, one uses a private field and a public property which transforms the field's value in such a way that its default value will map to the desired default for the structure. For example, you could have a backing field int _x_minus_1200; and have a property getter which returns _x_minus_1200 + 1200. I'm not hugely keen on such approaches (generally I prefer for structures to have public fields and behave like structures, and have the meaning and validation of structure fields be a function of the code that uses the structures) but in some cases they can be helpful.
I have a basic class with this method including
public class Account
{
//MEMBERS
private int acctNo;
protected double balance;
public double deposit;
// CONSTRUCTORS
public Account() //member intitilization
{
acctNo = 54534190;
balance = 7500;
deposit= 1500;
}
//PROPERTIES
public int AcctNo
{
get {return acctNo; }
set {acctNo = value; }
}
public double Balance
{
get { return balance; }
set { balance = value; }
}
public double Deposit
{
get {return deposit; }
set {deposit = value; }
}
public virtual double getDeposit (double amount)
{
double transactionAmt=0.00;
if (amount>0)
{
balance+=amount;
transactionAmt= amount;
}
return transactionAmt;
}
Now in my actual program I am trying to output this method. What would my writeline look like?
I tried to write this:
static void Main(string[] args)
{
Console.WriteLine("CREATING ACCOUNT");
Account myAcctDefault = new Account();
DumpContents(myAcctDefault);
Pause();
}
static void DumpContents(Account account)
{
Console.WriteLine(" output {0}", account.getDeposit());
}
I am getting an error saying:
no overload for method 'getDeposit' takes 0 arguments.
What am I doing wrong, am I trying to output this method incorrect?
Any help, insight or suggestions would be extremely helpful.
I am new to c# as I'm sure you can tell. What is the proper process to output a method in this context?
I am getting an error saying "no overload for method 'getDeposit' takes 0 arguments". What am I doing wrong
Exactly what it says. Here's your method call:
Console.WriteLine(" output {0}", account.getDeposit());
... and here's the method declaration:
public virtual double getDeposit (double amount)
Note how the method declares a parameter - but you're not providing an argument. Either you need to get rid of the parameter, or you need to add an argument to the method call. Or you need to change to using a different method - one which doesn't change the balance of the account. (It seems unlikely that you want to do that in this case.) Perhaps you should add a Balance property:
// Please note that this should probably be decimal - see below
public double Balance { get { return balance; } }
Then call it with:
Console.WriteLine(" output {0}", account.Balance);
Additionally:
For financial quantities, it's generally better to use decimal than double. Read my articles on decimal floating point and binary floating point for more information.
Your getDeposit method doesn't follow .NET naming conventions, where (at least public) methods are named in PascalCase, with a leading capital letter
Your getDeposit method is oddly named as it isn't "getting" a deposit - it's making a deposit (and returning the balance)
Your getDeposit method always returns the value passed into it, unless it's negative. That seems odd to me - if it's going to return anything, shouldn't it return the balance?
Your getDeposit method silently ignores negative deposits. I'd expect this to throw an error, as trying to make a negative deposit indicates a programming error IMO.
Your getDeposit method takes one argument that you are not passing to it. Depends what you want to achieve either pass a value to method:
static void DumpContents(Account account)
{
double deposit = 1000;
Console.WriteLine(" output {0}", account.getDeposit(deposit));
}
or remove this argumentparameter from the method signature.
//You have to pass a double value into the method, because there is only one method
//and wants a double paramater:
//this is what you created:
public double getDeposit(double amount) // <-
{
double transactionAmt = 0.00;
if (amount > 0)
{
balance += amount;
transactionAmt = amount;
}
return transactionAmt;
}
//This how you should call it:
static void DumpContents(Account account)
{
Console.WriteLine(" output {0}", account.getDeposit(34.90)); //<-
}
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.