I have a set of instance fields inherited from class G481Vars by object G481Var.
G481Vars G481Var = new G481Vars();
The values of the instance fields are assigned to through this function
private void AssignValuesG481()
{
HtmlInputText[] G481Inputs = new HtmlInputText[13] //Create an explicit array of type HtmlInputText to handle elements of input boxes on G481 tab.
{
G481Disp_Txt, G481IniVel_Txt, G481FinVel_Txt, G481Acc_Txt,
G481Time_Txt, G481Force_Txt, G481Mass_Txt, G481Weight_Txt,
G481Press_Txt, G481Dens_Txt, G481Energy_Txt, G481Area_Txt,
G481Vol_Txt
};
double[] G481List = new double[13] //Create an explicit array of type double that stores the instance fields of class G481Vars
{
G481Var.Disp, G481Var.IniVel, G481Var.FinVel, G481Var.Acc,
G481Var.Time, G481Var.Force, G481Var.Mass, G481Var.Weight,
G481Var.Press, G481Var.Dens, G481Var.Energy, G481Var.Area,
G481Var.Vol
};
for (int i = 0; i <= 12; i++) //Perform the iterative loop
{
if (G481Inputs[i].Value != "")
{
double.TryParse(G481Inputs[i].Value, out G481List[i]);
}
}
}
Where G481Vars is Defined as:
public class G481Vars
{
public double Disp { get; set; }
public double IniVel { get; set; }
public double FinVel { get; set; }
public double Acc { get; set; }
public double Time { get; set; }
public double Force { get; set; }
public double Mass { get; set; }
public double Weight { get; set; }
public double Press { get; set; }
public double Dens { get; set; }
public double Energy { get; set; }
public double Area { get; set; }
public double Vol { get; set; }
}
However when i try and access these instance fields from another function CalculateG481_Click They always return 0, even though they are assigned to before hand.
protected void CalculateG481_Click(object sender, EventArgs e)
{
AssignValuesG481();
TempInputDebugField.Value = Convert.ToString(G481Var.Disp); //This always returns 0 in the field, even though <>0 was put into the disp input field and assignvariables run.
}
When I put the TempInputDebugField code into the AssignValuesG481 function it returns the correct value. Any ideas on what is going on with the instance field?
Thanks for your help.
It seems like you think that setting the value of an element of G481List will forward that value on to the corresponding property of G481Var that was used to initialize the array. That is not true. all it does is change the values within the array.
You'll need to set the values of the instance explicitly. You could use reflection to set the properties dynamically, but with only 13 properties it would be much safer and cleaner to just set them explicitly:
G481Var.Disp = double.Parse(G481Inputs[0].Value)
G481Var.IniVel = double.Parse(G481Inputs[1].Value)
G481Var.FinVel = double.Parse(G481Inputs[2].Value)
G481Var.Acc = double.Parse(G481Inputs[3].Value)
G481Var.Time = double.Parse(G481Inputs[4].Value)
G481Var.Force = double.Parse(G481Inputs[5].Value)
G481Var.Mass = double.Parse(G481Inputs[7].Value)
G481Var.Weight = double.Parse(G481Inputs[8].Value)
G481Var.Press = double.Parse(G481Inputs[9].Value)
G481Var.Dens = double.Parse(G481Inputs[10].Value)
G481Var.Energy = double.Parse(G481Inputs[11].Value)
G481Var.Area = double.Parse(G481Inputs[12].Value)
G481Var.Vol = double.Parse(G481Inputs[13].Value)
From there you can use TryParse to better handle bad values, you can try using reflection to reduce duplicate code (at the expense of compile-time safety), etc. The point is to get something that works, then find ways to make it better. You can always go back to less "elegant" code if you get tired or stuck trying to refactor it.
Try this :
for (int i = 0; i <= 12; i++) //Perform the iterative loop
{
double val;
if (G481Inputs[i].Value != "")
{
double.TryParse(G481Inputs[i].Value, out val);
G481List[i] = val;
}
}
double is a valuetype, so when you parse the strings the values are stored only in the array. You will have to assign this values to G481Var properties:
double value;
if (double.TryParse(G481Disp_Txt.Value, out value)
G481Var.Disp = value;
Do this for each property and should works fine
Related
I am experimenting with a nested object class for an upcoming software project, in C#. I know how to do computed fields/properties within a class, at least as far as setting it programmatically with something like the date.
This is a little different. I am setting up a nested class like this:
string Test { get; set; }
List<Line> Detail { get; set; }
decimal Total {
get {
return TotalOf();
}
}
decimal TotalOf() {
var listQuery = this.Detail;
// This is where I'm trying to figure out how to do.
// I want the TotalOf function to return the sum of the
// Cost fields of the contained list items (Line is defined below).
// I will remove the "return 0;" eventually once
// I can figure out how to do the calculation.
return 0;
}
public class Line {
int indexOf { get; set; }
decimal Cost { get; set; }
}
That way, the field Total is automatically calculated rather than me having to compute it through the code consuming this class.
I have tried searching all over but I can't seem to find the right answer. I have plenty of time to do this, and worst case, I can just do it in the program consuming this class, but I thought I'd ask. When I hit the . after typing in this.Detail, the only aggregate function that comes up is Count.
I have tried to use the Detail.Sum function, hoping the Linq would bring up a lambda expression that I could then say "add up the Cost" but it won't come up.
I know this should be simple but I can't figure it out.
First, set access modifiers for Line properties like as public or other. Because, on default state it is private.
public class Line
{
public int indexOf { get; set; }
public decimal Cost { get; set; }
}
Then, set up root class like as LineCollection.
public class LineCollection
{
public class Line
{
public int indexOf { get; set; }
public decimal Cost { get; set; }
}
public string Test { get; set; }
public List<Line> Detail { get; set; }
public decimal Total { get; set; }
}
On LineCollection initialize default values for properties on constructor:
public class LineCollection
{
public class Line
{
public int indexOf { get; set; }
public decimal Cost { get; set; }
}
public string Test { get; set; }
public List<Line> Detail { get; set; }
public decimal Total { get; set; }
public LineCollection()
{
this.Test = string.Empty;
this.Detail = new List<Line>();
}
}
After this modify get/set accessors for Total property. I guess, property is read only and we not need to define set accessor.
public decimal Total
{
get
{
return this.Detail.Sum(x => x.Cost);
}
}
Code in get accessor automatically runs when we trying to get his value. Finally, we can run tests for checks.
LineCollection collection = new LineCollection();
collection.Detail.Add(new LineCollection.Line() { indexOf = 0, Cost = 43.3m });
collection.Detail.Add(new LineCollection.Line() { indexOf = 1, Cost = 23 });
collection.Detail.Add(new LineCollection.Line() { indexOf = 3, Cost = 56.21m });
Console.WriteLine(collection.Total.ToString());
It returns 122,51.
Think this method would work for you:
decimal TotalOf() {
return this.Detail.Select(line => line.Cost).Sum();
}
I believe this way also works:
decimal TotalOf() {
return this.Detail.Sum(line => line.Cost);
}
Hope this helps :)
How to use Property inside method in right way. I was searching on the internet but I can't found property is used inside method that will be returned value.
public class OET
{
public int ShiftTime { get; set; }
public int BreakTime { get; set; }
public int DownTime { get; set; }
public int ProductionTarget { get; set; }
public int IdealRunRate { get; set; }
public int PrductionOneShift { get; set; }
public int RejectedProduct { get; set; }
public int planedProductionTime(int shift, int breaktime) {
shift = ShiftTime;
breaktime = BreakTime;
return shift - breaktime;
}
I would like to use property to get value from "PlanedProductionTIme" method, is it code above right?
Your example isn't very clear, because you're passing in two parameters, but then ignoring them in your calculation. But if your intention was to have a property returning the calculated PlannedProductionTime, it can go like this:
public int PlannedProductionTime
{
get { return ShiftTime - BreakTime; }
}
Note that this is instead of the method - a property is a syntactic way to have a method accessed like a property:
OET myOet = new OET();
int plannedProductionTime = myOet.PlannedProductionTime;
there is no use of "sift" and "breaktime" local variable into is function. just use return ShiftTime-BreakTime.
public int method2() {
///here you are getting the peroperties value and doing calculations returns result.
return ShiftTime -BreakTime;
}
if your requirement is to set the properties value.
public void method1(int shift, int breaktime) {
ShiftTime= shift ;
BreakTime = breaktime;
}
public int PlanedProductionTime { get { return ShiftTime - BreakTime; } }
You can define the property as a calculated ones, by defining the get method in it.
More solutions - you can define a separate function and call it inside get. It will help if you want to do some more complex calculations which needs to be used somewhere else in the class - private or outside class - public.
public int PlanedProductionTime { get { return _calculatePlannedProductionTime( ShiftTime, BreakTime); } }
private\public int _calculatePlannedProductionTime (int shift, int break)
{
return shift - break;
}
I wrote a parse class trying to handle parsing the data from a string array into it's appropriate value. I am trying to test this program to see if it will print out the value parse.open, and it is not. It is printing up 0's for the moment (which isn't accurate), until i could figure out why it's not showing what I need.
while (!r.EndOfStream)
{
ParseFileRead parse = new ParseFileRead();
string line = r.ReadLine();
//Send this to Parse class
string [] values = line.Split(',');
//parse records
Console.WriteLine(values[6]); //This is printing the accurate value for parse.open
ParseFileRead.Parse(values);
Console.WriteLine(parse.open); //This is not printing the accurate value
}
Console.Read();
vWriteFile.Close();
And here is my ParseFileRead class:
public class ParseFileRead
{
public int open { get; set; }
public int buy { get; set; }
public int sell { get; set; }
public double settleMM { get; set; }
public string account { get; set; }
public string underlying { get; set; }
public string symbol { get; set; }
public static void Parse(string[] arr)
{
ParseFileRead parse = new ParseFileRead();
parse.account = arr[0];
parse.underlying = arr[12];
parse.symbol = arr[1];
parse.open = Convert.ToInt32(arr[6]);
parse.buy = Convert.ToInt32(arr[7]);
parse.sell = Convert.ToInt32(arr[8]);
parse.settleMM = Convert.ToDouble(arr[10]);
}
}
This is actually correct.
The default value for an uninitialized int is 0.
You are creating a new instance of your ParseFileRead class which will have a value of 0 for open. You then check your parsed value to make sure it's reading in correctly using Console.WriteLine(values[6]);.
Next, you try to parse your values using the Parse function of your ParseFileRead class; which is a void function so it has no return value.
Inside your Parse function you have: ParseFileRead parse = new ParseFileRead(); which creates yet another new instance of your class with a value of 0 for open. This particular instance is never used anywhere and is not the same as the values of the properties created with your initial instance of ParseFileRead
If you put a Console.Write in your Parse function, I'm sure that you will see it being parsed correctly.
So you have 2 options:
Set the properties of your ParseFileRead inside the Parse class without creating a new instance of ParseFileRead
Return the newly created ParseFileRead instance out of your Parse function.
Or a 3rd Option, which is probably best as suggested by Plutonix:
/*Parse class*/
public class ParseFileRead
{
public int open { get; set; }
public int buy { get; set; }
public int sell { get; set; }
public double settleMM { get; set; }
public string account { get; set; }
public string underlying { get; set; }
public string symbol { get; set; }
public ParseFileRead(string[] arr)
{
this.account = arr[0];
this.underlying = arr[12];
this.symbol = arr[1];
this.open = Convert.ToInt32(arr[6]);
this.buy = Convert.ToInt32(arr[7]);
this.sell = Convert.ToInt32(arr[8]);
this.settleMM = Convert.ToDouble(arr[10]);
}
}
/*Parsing code*/
while (!r.EndOfStream)
{
string line = r.ReadLine();
//Send this to Parse class
string [] values = line.Split(',');
//parse records
Console.WriteLine(values[6]); //This is printing the accurate value for parse.open
ParseFileRead parse = new ParseFileRead(values);
Console.WriteLine(parse.open); //This is not printing the accurate value
}
I have an array in C#:
string[] foo = new string[11];
The length of foo array has been 10, I only changed it to 11 because I needed an extra value. My only problem is: I can't seem to change the length of the array. If I change it to 11, like in the above example, set a break point and debug, after the compiler passes this line, it still has a length of 10.
Now when I add a watch foo = new string[11] after the compiler passes this line, all the values are erased and the length is changed to 11. Basically I have no idea what is going on, especially why adding a watch has an effect on the runtime values of variables.
Does anybody have any idea what is happening here?
public string[] getValues()
{
//Why does this only have 10 dimensions after initialization?????
string[] values = new string[11];
string[] temp = ddlProjectnumber.Text.Split('-'); //<----- here I set break point.
values[0] = temp[0].Trim();
values[1] = tbTask.Text;
values[2] = ddlSubstitute.Text;
values[3] = ddlCategory.Text;
values[4] = ddlSubcategory.Text;
values[5] = cbFinished.Checked.ToString();
if (propertychanged)
{
values[6] = DateTime.Now.ToString();
}
values[7] = cbJourney.Checked.ToString();
return values;
}
Your code will be easier to maintain if you create a class to hold your values:
public class MyClass
{
public string ProjectNumber { get; set; }
public string Task { get; set; }
public string Substitute { get; set; }
public string Category { get; set; }
public string Subcategory { get; set; }
public bool Finished { get; set; }
public DateTime? PropChangedDate { get; set; }
public bool Journey { get; set; }
}
Then adjust your method to just populate an instance of the class and return that instead:
public MyClass GetValues()
{
var myClass = new MyClass
{
ProjectNumber = ddlProjectnumber.Text.Split('-').First().Trim(),
Task = tbTask.Text,
Substitute = ddlSubstitute.Text,
Category = ddlCategory.Text,
Subcategory = ddlSubcategory.Text,
Finished = cbFinished.Checked,
Journey = cbJourney.Checked
};
if (propertychanged)
myClass.PropChangedDate = DateTime.Now;
return myClass;
}
Now you don't have to guess which values were stored in each element of the array.
okay I played around a bit and after changing my configuration from debug to release and then to debug again, it apparently fixed itself. I guess it really was old code, but for some reason, it did not recompile correctly after I cleaned and rebuild my solution. anyway it works now :)
say i have a some properties
public int redBalls { get; set; }
public int blueBalls { get; set; }
I now want to have a totalBalls property which will add the two.
Would I do this?
public int totalBalls { get { return redBalls + blueBalls; } }
I'm trying this but the result is 0
*edit, i've spoken to my lead developer and it's because whatever accesses totalBalls isn't notified of the changes of redBalls or blueBalls so it wont recalculate those values
So I have to do OnPropertyChanged("total")
Wrote a test for you... This succeeds for me.
[Test]
public void SO()
{
var testing = new Testing();
Assert.AreEqual(0, testing.RedBalls);
Assert.AreEqual(0, testing.BlueBalls);
Assert.AreEqual(0, testing.TotalBalls);
testing.RedBalls = 2;
testing.BlueBalls = 4;
Assert.AreEqual(2, testing.RedBalls);
Assert.AreEqual(4, testing.BlueBalls);
Assert.AreEqual(6, testing.TotalBalls);
}
class Testing
{
public int RedBalls { get; set; }
public int BlueBalls { get; set; }
public int TotalBalls { get { return RedBalls + BlueBalls; } }
}
You must acutally set the value of redBalls/blueBalls
class Balls
{
public int redBalls { get; set; }
public int blueBalls{ get; set; }
public int totalBalls{ get{ return redBalls + blueBalls; } }
}
void test()
{
// You must acutally set the value of redBalls/blueBalls
var balls = new Balls{ redBalls = 1, blueBalls = 2 };
Assert.AreEqual(3, balls.totalBalls);
}
There is nothing wrong with your code except the capitalisation of the Property names, which is purely cosmetic.
totalBalls will = 0 whilst the sum of redBalls and blueBalls is 0, obviously, they will both = 0 until they are set to some other value.
EDIT
You didn't mention DependecyPropertys in the OP or the tags, if a dependecy property is bound to the totalBalls property it won't know that totalBalls is calculated from other properties.
You should extend the definition of your dependency property so that its metadata includes a PropertyChangedCallback that can detect the aggregated changes, rather than coupling your simple class to WPF.