Calculate Variable value with the help of get and set Method - c#

I am geting data with the help of get and set methods. I want to calculate waste value. This is how I have tried to solve this issue.
class OSSP
{
private decimal waste;
public int DocNum { get; set; }
public string U_ItemCode { get; set; }
public string U_ItemName { get; set; }
public string U_ItemDesc { get; set; }
public string U_WetProcess { get; set; }
public string U_Color { get; set; }
public string U_Size { get; set; }
public decimal U_knitgWeight { get; set; }
public decimal U_FinishWeight { get; set; }
OSSP ossp ;
public decimal Waste
{
get => waste;
set
{
waste = ossp.U_knitgWeight - ossp.U_FinishWeight;
}
}
}

since you want Waste to be calculated from values of other properties and you want to have this value when you try to access this property you need to put the calculation code into the getter.
public decimal Waste
{
get => this.U_knitgWeight - this.U_FinishWeight;
}
furthermore it doesn't make sense to allow this value to be set, because it's meaning is based on the calculation of an internal state that is not visible outside. So that means that you can remove the setter entirely. By doing so you can also remove the private decimal waste; field because it is superfluous now.
EDIT:
One more thing that I notice is that you have an internal OSSP ossp; field, which is never set anywhere in your code. I assume you want to calculate with the actual values of the current object. So in this case you need to use this. before the 2 properties which you use for calculation.
Correct me if I am wrong here, because you might have purpose as why you made this OSSP ossp; field

get
{
return ossp.U_knitgWeight - ossp.U_FinishWeight;
}
When get method gets called it returns value after calculating.

Related

Creating class members during run time - C#

I have a simple class defined like this:
public class StickColumns
{
public string wellname { get; set; }
public double WellLength { get; set; }
}
In the code, I get some data as list<double> perfdepth; assume this is perfdepth1,perfdepth2,perfdepth3. Of course, this list is dynamic hence, I wouldnt know beforehand to change my class definition to:
public class StickColumns
{
public string wellname { get; set; }
public double WellLength { get; set; }
public double perfdepth1 { get; set; }
public double perfdepth2 { get; set; }
public double perfdepth3 { get; set; }
}
Can these new members be created during run time?
The reason why I think I would need this is because of data binding in WPF. Eventually I need to display "point series"; Perfdepth1 as one series, perfdepth2 as another series and so on, i.e, dynamic number of Perfdepths.
If there is a simpler way to do it, I am all ears!
You might just want to use the dynamic type with ExpandoObject..
dynamic stickColumns = new ExpandoObject();
stickColumns.wellName = "Something";
stickColumns.perfdepth1 = "Something Else";
It has its drawbacks as it does mean you end up with runtime errors etc... but it can be useful for this type of scenario.

Specifying a format inside of a class

I'm currently writing some software for a jumping-competition.
I've made a class to put my riders in and in this class theres also a variable to store the timing of the rider. I'm using a timespan for this as I also need to use milliseconds.
This is not a problem so far.
However, when I link my list with riders to a datagridview, the value of the time is being represented as 00:00:00 while I would need it to be 00:00.000
Is there a way that I can specify the outputstring either in my class or in my datagridview?
I know I could fill the datagridview manually and bypass the issue that way, but that doesn't really make sense.
So how can I tackle this problem?
Cheers,
Kenneth
public class RidersClass
{
public string firstnameRider { get; set; }
public string lastnameRider { get; set; }
public string nameHorse { get; set; }
public string Stable { get; set; }
public TimeSpan timeRound { get; set; }
public int penalty { get; set; }
}
Riders = new List<RidersClass>();
private void showList()
{
var source = new BindingSource();
source.DataSource = Riders;
grdRiders.DataSource = source;
}
One way to do it would be to create a wrapper class around TimeSpan like this
public class TimeSpanWrapper
{
public TimeSpan Time{get;set;}
public override string ToString()
{
return string.Format("{0}:{1}.{2}",Time.Hour,Time.Minute,Time.Second);
}
}
Then replace the TimeSpan object in your class with the TimeSpanWrapper, when the binding will occur for this class the ToString() method will be called and return the string in the format you like.

class for this JSON

I am hitting an API that returns some JSON as follows:
{"stats":{"X":{"Name":"X","Found":"Yes"}},"response":"OK","runtimeMs":798}
I would like to generate C# classes for it and I used json2sharp, it generated classes such as root object which i modified as follows:
public class RootObject
{
public Stats stats { get; set; }
public string response { get; set; }
public int runtimeMs { get; set; }
}
public class Stats
{
public string name { get; set; }
}
public class Variant
{
public string name { get; set; }
public string Found { get; set; }
}
The issue i am facing is that in the class Stats I have used name since the json will reply with any name such as X or Y or Z.
I am able to deserialise the JSON into the root object but cannot get any data into the stats class.
JsonConvert.DeserializeObject<RootObject>(response.Content);
Any ideas why i might be doing incorrectly?
Your problem is similar to this How can I parse a JSON string that would cause illegal C# identifiers?
So, your model should be
public class Variant
{
public string Name { get; set; }
public string Found { get; set; }
}
public class RootObject
{
public Dictionary<string, Variant> stats { get; set; }
public string response { get; set; }
public int runtimeMs { get; set; }
}
EDIT
#evanmcdonnal if use a dictionary as shown in the EZI's answer or an object with fields named X, Y, and Z you have to perform nullity or keyexists checks all over the place in order to safely use the object.
I don't think this simple linq is hard to write
rootObj.stats.Values.Where(....);
or
rootObj.stats.Keys.Select(....);
That is happening because json.NET is looking for a property name in your class which matches the field name in the json. Since name does not resemble anything in the json it finds nothing.
There are a couple of options for how to work around this. You can use an annotation to say what the json field you want to put there is, or you can change the name of the property. However, from you post it sounds like you're saying there could be an object called X or an object called Y in the json, neither of those options will make that deserialize correctly in all cases. I'll edit with some ideas for how you may want to handle that.
Based on OP's comment, here's what you're looking for;
public class RootObject
{
public Stats stats { get; set; }
public string response { get; set; }
public int runtimeMs { get; set; }
}
public class Stats
{
public Varient X { get; set; }
public Varient Y { get; set; }
public Varient Z { get; set; }
}
public class Variant
{
public string name { get; set; }
public string Found { get; set; }
}
In other places in your code you just have to have two code paths or do a conversion to avoid doing nullity checks everywhere.
if (myInstance.X != null)
// it was X that was in the json
else if (myInstace.Y != null)
// it was Y
else
// not sure what happened, perhaps neither X nor Y were present.
Now the other option is to make this just an intermediary then you define another type that just has one property named name and you give it a constructor that takes a RootObject and assigns whichever value isn't null to it's name property or whatever you want to call it. I would probably do something like this myself because if use a dictionary as shown in the EZI's answer or an object with fields named X, Y, and Z you have to perform nullity or keyexists checks all over the place in order to safely use the object.

Changing a model without altering the database?

I've got a model being used to populate a database
public class Account
{
public int NumberOfPayPeriods { get { return 24; } }
public decimal YearAmount { get; set; }
public decimal PlanTotal
{
get { return NumberOfPayPeriods*YearAmount; }
}
}
The NumberOfPayPeriods attribute I need to change from just a get to a get; set;
However, when I change this, I get an EntityCommandExecutionException (invalid column name). I assume this is because it is trying to map this to the database where there previously existed no such column (as it was only a get).
Is there any way I can change this to a get;set; without having to delete the table? There's a lot of important data on there that cannot be lost or re-created.
Add a [NotMapped] attribute over the property you don't want stored.
public class Account
{
[NotMapped]
public int NumberOfPayPeriods { get { return 24; } set { ... } }
public decimal YearAmount { get; set; }
public decimal PlanTotal
{
get { return NumberOfPayPeriods*YearAmount; }
}
}

Why Does Lack of Cohesion Of Methods (LCOM) Include Getters and Setters

I am looking at the LCOM metric as shown here,
http://www.ndepend.com/Metrics.aspx
So we are saying a few things,
1) A class is utterly cohesive if all its methods use all its instance fields
2) Both static and instance methods are counted, it includes also constructors, properties getters/setters, events add/remove methods
If I look at a class such as this,
public class Assessment
{
public int StartMetres { get; set; }
public int EndMetres { get; set; }
public decimal? NumericResponse { get; set; }
public string FreeResponse { get; set; }
public string Responsetype { get; set; }
public string ItemResponseDescription { get; set; }
public string StartText { get; set; }
public decimal? SummaryWeight { get; set; }
}
It gets a bad score of 0.94 because each getter and setter doesn't access 'all of the other instance fields'.
It is calculated like this,
accessAverage - methodCount / 1 - methodCount
(2 - 17) / (1 - 17) = 0.94 (rounded)
I am not understanding this metric, why should it include getters and setters? A getter and setter will always only access one single instance field.
This demonstrates that every software metric is flawed if you blindly take it to its extreme.
You know an "incohesive" class when you see one. For example:
class HedgeHog_And_AfricanCountry
{
private HedgeHog _hedgeHog;
private Nation _africanNation;
public ulong NumberOfQuills { get { return _hedgeHog.NumberOfQuills; } }
public int CountOfAntsEatenToday { get { return _hedgeHog.AntsEatenToday.Count(); } }
public decimal GrossDomesticProduct { get { return _africanNation.GDP; } }
public ulong Population { get { return _africanNation.Population; } }
}
This is obviously an incohesive class, because it contains two pieces of data that don't need to be with one another.
But while it's obvious to us that this class is incohesive, how can you get a software program to determine incohesion? How would it tell that the above class is incohesive, but this isn't?
class Customer
{
public string FullName { get; set; }
public Address PostalAddress { get; set; }
}
The metric they came up with certainly detects incohesion, but also comes up with false positives.
What if you decided this metric was important? You could create a "CustomerData" class containing just fields, and a "Customer" class that exposes the data fields as properties.
// This has no methods or getters, so gets a good cohesion value.
class CustomerData
{
public string FullName;
public Address PostalAddress;
}
// All of the getters and methods are on the same object
class Customer
{
private CustomerData _customerData;
public string FullName { get { return _customerData.FullName; } }
// etc
}
But if I'm playing this game, I can apply it to the incohesive example as well:
class Hedgehog_And_AfricanCountry_Data
{
public Hedgehog _hedgehog;
public AfricanNation _africanNation;
}
class Hedgehog_And_AfricanCountry
{
private Hedgehog_And_AfricanCountry_Data _hedgehogAndAfricanCountryData;
// etc;
}
Really, I think it's best to understand what cohesion is, and why it's a worthwhile goal, but also understand that a software tool can not properly measure it.

Categories