C# Accessing a property within a property? - c#

I'm trying to pass some tests in the Exercism C# exercise 'weighing machine' which uses properties. I have these properties:
using System;
enum Units
{
Pounds,
Kilograms
}
class WeighingMachine
{
private decimal inputWeight;
public decimal InputWeight
{
get { return inputWeight; }
set { if (value >= 0)
inputWeight = value;
else throw new ArgumentOutOfRangeException();
}
}
private decimal displayWeight;
public decimal DisplayWeight
{
get
{ return displayWeight; }
set
{
displayWeight = InputWeight - TareAdjustment;
if (displayWeight <= 0)
throw new ArgumentOutOfRangeException();
}
}
private decimal _pounds;
public USWeight USDisplayWeight
{
get { return _pounds; }
set { _pounds = new USWeight(InputWeight).Pounds; }
}
public decimal TareAdjustment { private get; set; }
public int Units
{ get; set; }
}
struct USWeight
{
public USWeight(decimal weightInPounds)
{
Pounds = (int)weightInPounds;
Ounces = (weightInPounds - Pounds)*16;
}
public int Pounds { get; set; }
public decimal Ounces { get; set; }
}
My stumbling block is the tests:
[Fact]
public void Get_us_display_weight_pounds()
{
var wm = new WeighingMachine();
wm.InputWeight = 60m;
Assert.Equal(132, wm.USDisplayWeight.Pounds);
}
I can't get my head around how the test is asking for wm.USDisplayWeight.Pounds - how is the .Pounds accessed on the end? it's like there is a property set within the USDisplayWeight property, but that's not possible is it? I can't make the compiler stop complaining about the .Pounds - I get ''decimal' does not contain a definition for 'Pounds' and no accessible extension method 'Pounds' accepting a first argument of type 'decimal' could be found.
I'm sure it's a simple thing that I'm overlooking here, but I would appreciate any help at all.

Related

Can property setter condition acitvate by constructor?

I was expected that constructor can go into the setter condition, I have done the following attempts.
static void Main(string[] args)
{
Iitem car = new Car(7000);
Console.WriteLine($"cost={car.cost}");//expect output "too expensive",but actually show 7000
car.cost = 7000;
Console.ReadLine();
}
public interface Iitem
{
int cost { get; set; }
string status {get;set; }
}
class Car:Iitem
{
private int mycost;
public int cost
{
get { return mycost; }
set
{
if (value > 5000)
{
mycost = 0;
Console.WriteLine("too expensive");
}
else
{
mycost = value;
}
}
}
public string status { get; set; }
public Car(int cost)
{
this.mycost = cost;
}
}
If I discard car.cost=7000 from Main() function, then I can't get the output of too expensive.
you are not getting the desired result because you are setting the value directly into the variable "mycost" in the constructor. Replace it with this.cost = cost;

i have a problem with my adaptive moving average trading system

I created a trading system with an adaptive moving average on the average true range but the program reports this error to me
the modifier public is not valid for this item
at line 21 of the code
public int avgTrueRange.value1 { get; set; }
I tried to change public but it always reports this error.
this is the code :
public class MediaMobileAdattiva : SignalObject
{
public MediaMobileAdattiva(object _ctx): base(_ctx)
{
Range = 14;
FirstLength = 10;
AvgTrueRange.value1 = 1;
}
private IOrderMarket buy_order;
public int Range { get; set; }
public double FirstLength { get; set; }
public int AvgTrueRange.value1 { get; set; }
private double FirstAverage()
{
if (AverageTrueRange < AvgTrueRange.value1)
return FirstLength;
}
protected override void Create()
{
// create variable objects, function objects, order objects
buy_order = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, EOrderAction.Buy));
}
protected override void StartCalc()
{
// assign inputs
}
protected override void CalcBar()
{
// strategy logic
if (Bars.CurrentBar > 1)
{
switch (FirstAverage)
{
case FirstLength:
return 1;
}
}
if (Bars.CurrentBar > 1 && Bars.Close.CrossesOver(FirstAverage, ExecInfo.MaxBarsBack)
{
switch (FirstLength)
{
case 1:
buy_order.Send(Bars.Close[0]);
}
}
}
}
What you need is to make a struct for AvgTrueRange:
public struct Range
{
public int value1 {get; set;}
}
and change:
public int AvgTrueRange.value1 { get; set; }
to
public Range AvgTrueRange { get; set; }
Your code still won't compile btw but I don't really understand what you are trying to do in this line:
if (AverageTrueRange < AvgTrueRange.value1)
Also, change:
switch (FirstAverage)
{
case FirstLength:
return 1;
}
to
var avg = FirstAverage();
int? result = avg switch
{
var avg when avg == FirstLength => 1,
_ => null
};
if (result.HasValue) return result.Value;
as cases can only be constant values.

C# limit options of enum in a derived class

So I'm trying to limit the options ,of an enum I declared in the base class, I can select in the derived class.
namespace FLYNET.Personeel
{
public enum Graad
{
Captain,
SeniorFlightOfficer,
SecondOfficer,
JuniorFlightOfficer,
Steward,
Purser
};
public abstract class VliegendPersoneelslid : Personeelslid
{
public VliegendPersoneelslid()
{
}
public override decimal BerekenTotaleKostprijsPerDag()
{
return BasisKostprijsPerDag;
}
public List<Certificaat> Certificaten { get; set; }
}
The above is the enum I'm trying to use from the base class Staff.
In the derived class Cabincrew I want to limit the options that can be selected in the constructor. If the wrong option is selected, it needs to throw a specified exception, so a bit like this :
namespace FLYNET.Personeel
{
public class CockpitPersoneel : VliegendPersoneelslid
{
public int VliegUren { get; set; }
public Graad Graad { get; set; }
public CockpitPersoneel()
{
if (Grade = Graad.Steward || Grade = Graad.Purser)
{
throw new Exception
}
}
public override decimal BerekenTotaleKostprijsPerDag()
{
decimal kostprijsPersoneel = 0m;
decimal percentage;
return kostprijsPersoneel;
}
}
}
I'm aware this is probably a beginners question (and it is :p) but please bear with me.
I suggest using extension methods in order to hide options
public enum Grade {
None, // <- zero option is often a good idea to include
Captain,
SeniorFlightOfficer,
SecondOfficer,
JuniorFlightOfficer,
Steward,
Purser };
public static class GradeExtensions {
public static bool IsCabinCrue(this Grade grade) {
return grade == Grade.Steward || grade == Grade.Purser;
}
public static bool IsCockpitPersonnel(this Grade grade) {
return grade == Grade.Captain ||
grade == Grade.SeniorFlightOfficer ||
grade == Grade.SecondOfficer ||
grade == Grade.JuniorFlightOfficer;
}
}
Then you can use extension methods as if their are methods of the enum when validating Grade values provided:
public class CabinCrue {
...
public CabinCrue(Grade grade) {
// Validation: Cabin Crue grade only
// not Exception but ArgumentException: it's argument grade that's wrong
if (!grade.IsCabinCrue())
throw new ArgumentException("Cabin crue only", "grade");
Grade = grade;
...
}
public Grade Grade {
get;
private set;
}
...
}
I think you have an error in logic. You are trying to verify the Grade or Graad in the constructor. The property Graad cannot be set before the constructor call. Your validation will check the default value of the variable Graad (which in your case will be Captain).
You would need to pass the Graad into the constructor to be able to make that validation:
public CockpitPersoneel(Graad g)
{
if (g = Graad.Steward || g = Graad.Purser)
{
throw new Exception("wrong choice");
}
else
{
this.Graad = g;
}
}
What you also could do is to put the Validation logic directly into the full property and throw there the exception:
Graad _myGrade;
public Graad GradeOfPerson
{
get { return _myGrade; }
set
{
if (value = Graad.Steward || value = Graad.Purser)
{
throw new Exception("Not Allowed");
}
_myGrade = value;
}
}
this way you can leave your constructor blank:
public CockpitPersoneel()
{
}

System.StackOverflowException was unhandled

Please help, I'm confused I do not know why the error logs
System.StackOverflowException was unhandled.
I keep getting an error on set LekID.
How would I that fix?
Here is the code:
public Lager(long lekID, string lek, string proizvojdac, int kolicina, double cena)
{
LekID = lekID;
Lek = lek;
Proizvodjac = proizvojdac;
Kolicina = kolicina;
Cena = cena;
}
public long LekID
{
get { return LekID; }
set { LekID = value; }
}
public string Lek
{
get { return Lek; }
set { Lek = value; }
}
public string Proizvodjac
{
get { return Proizvodjac; }
set { Proizvodjac = value; }
}
public int Kolicina
{
get { return Kolicina; }
set { Kolicina = value; }
}
public double Cena
{
get { return Cena; }
set { Cena = value; }
}
public long LekID
{
get { return LekID; }
set { LekID = value; }
}
This (and the other properties) cause a StackOverflowException, since you are assigning value to LekID over and over again.
You should add a field to the property and store the value there:
private long _lekID;
public long LekID
{
get { return _lekID; }
set { _lekID = value; }
}
You should give different names to your private variables and to your properties. Otherwise, your property is calling itself when you access it.
Example:
long _lekID;
public long LekID
{
get { return _lekID; }
set { _lekID = value; }
}
Or simply:
public long LekID { get; set; }
The properties are calling themself. Try changing your properties like this:
public string Lek
{
get;
set;
}
You're calling the Lek property recursively in both the setter and the getter
Either introduce a backing field:
private string lek;
public string Lek
{
get { return this.lek; }
set { this.lek = value; }
}
or use an Automatic Property:
public string Lek
{
get; set;
}
Marking this community wiki as it is only an aside, but none of this would have happened if you'd been sufficiently lazy (that is often a virtue in programming, not a vice):
public long LekID {get;set;}
public string Lek {get;set;}
public string Proizvodjac {get;set;}
public int Kolicina {get;set;}
public double Cena {get;set;}
less typing; no errors; and you've correctly exposed the API as properties so you can add validation / side-effects later if you need, and it'll work with binding APIs (which don't usually love fields).
Try using code snippet like prop/ propfull,
the snippets will create the properties code automaticly

StackOverflowException on a huge class

So, I got to work on this huge project. And the is this HUGE class with hundreds of variables and methods and lots of partial classes.
interface IBusinessReturn
{
string variableOne { get; set; }
string variableTwo { get; set; }
string variableHundred { get; set; }
//a lot more...
}
public partial class BusinessTransaction : IBusinessReturn
{
private string _variableOne;
public string variableOne
{
get { return variableOne; }
set { _variableOne= value; }
}
private string _variableTwo;
public string variableTwo
{
get { return variableTwo; }
set { _variableTwo = value; }
}
private string _variableHundred;
public string variableHundred
{
get { return variableHundred; }
set { _variableHundred = value; }
}
// And so it goes on till hundreds...
}
And lots of other partials that goes like this:
public partial class BusinessTransaction: IBusinessTransaction238
{
//Lots of methods
}
The problem is: It is all working except for some new variables I declared. (varOne and Two, in the example above). When I try to set any value to these var I got a StackOverflowException. I'm 100% sure they're declared just like every other.
This is how i'm calling:
BusinessTransaction v763 = new BusinessTransaction();
v763.variableHundred = "Hi"; //working
v763.variableOne = "Hello"; //StackOverflow HERE.
I just can't see any reason for why this is happening, and I only hope you can tell me if this have something to do with the huge amount of methods and variables on this class..
Look at your getter - no underscores for any of them. You're causing an infinite loop.
public string variableOne
{
get { return variableOne; }
set { _variableOne= value; }
}
It should return private member, not itself.
Should be
public string variableOne
{
get { return _variableOne; // error was here
}
set { _variableOne= value; }
}

Categories

Resources