Accessing Class Items from Method [duplicate] - c#

This question already has answers here:
Use a variable from another method in C#
(2 answers)
Closed 1 year ago.
This seems like an easy question to find the answer to, but I can't find anything quite like this.
I have a class file named Earnings.cs, that will only hold two items (lastYear, thisYear).
The code I have is as follows
public void parseEarnData(List<String> earningData)
{
... //gets the information
classAdd(lq1, lq2, lq3, lq4, tq1, tq2, tq3, tq4);
}
public void classAdd(string lqO, string lqT, string lqTh, string lqF, string tqO, string tqT, string tqTh, string tqF)
{
Earnings lastYear = new Earnings(Convert.ToDecimal(lqO), Convert.ToDecimal(lqT), Convert.ToDecimal(lqTh), Convert.ToDecimal(lqF));
Earnings thisYear = new Earnings(Convert.ToDecimal(tqO), Convert.ToDecimal(tqT), Convert.ToDecimal(tqTh), Convert.ToDecimal(tqF));
}
Then in a method that actually does math, I would like to retrieve lastYear and thisYear. Everything in the class is public, but lastYear and thisYear do not exist in the context of the method for calculations. So my question is how do I access them?
Class if you think it's important
public class Earnings
{
public decimal q1 { get; set; }
public decimal q2{ get; set; }
public decimal q3{ get; set; }
public decimal q4{ get; set; }
public Earnings(decimal q1, decimal q2, decimal q3, decimal q4)
{
this.q1 = q1;
this.q2 = q2;
this.q3 = q3;
this.q4 = q4;
}
}
Edit: The variable names just stand for Last Quarter One, Two, etc. and This Quarter One, Two, etc. Sorry for the weird abbreviations.
Edit 2: All the code is written within my Form's class (Form1.cs), and the method that will do the calculations on the data will also be located within the same class. I just want to be able to access the data from the Earnings class in my main code.

All the code is written within my Form's class (Form1.cs), and the method that will do the calculations on the data will also be located within the same class.
Then you'll probably want to make lastYear and thisYear part of your form too:
public partial class Form1 : Form
{
// declare Earnings members
Earnings lastYear;
Earnings thisYear;
// ...
public void classAdd(string lqO, string lqT, string lqTh, string lqF, string tqO, string tqT, string tqTh, string tqF)
{
// assign values to declared instance members
lastYear = new Earnings(Convert.ToDecimal(lqO), Convert.ToDecimal(lqT), Convert.ToDecimal(lqTh), Convert.ToDecimal(lqF));
thisYear = new Earnings(Convert.ToDecimal(tqO), Convert.ToDecimal(tqT), Convert.ToDecimal(tqTh), Convert.ToDecimal(tqF));
}
public void doActualWork()
{
// now you can access lastYear and thisYear in this scope too
}
}
It's not important which source code file contains the definition for Earnings - it's just a blueprint we can use elsewhere :-)

Related

Method to return a List<T> from a List<OwnStruct>, where List<T> then contains only one Property of all OwnStructs in List (C#) [duplicate]

This question already has answers here:
convert a list of objects from one type to another using lambda expression
(14 answers)
Closed 1 year ago.
I'm struggling with this a little.
I have a List<HeadStruc_Table> within my program.
The Class HeadStruct looks like following:
public partial class HeadStruct_Table : IComparable<HeadStruct_Table>
{
public string colName { get; set; }
public string colName_edit { get; set; }
public string alternativeNames { get; set; }
public int Table_ID { get; set; }
public bool colFound { get; set; }
public CheckBox cBox { get; set; }
I don't know how to create a method with parameters (List<HeadStruct_Table>, HeadStruct_Table.colName) that then returns a List<TypeOf(HeadStruct_Table.colName)> containing only the values of colName in this specific case.
Of course it should work for the bool and even CheckBox property as well.
As parameter HeadStruct_Table.colName doesn't work right now, as it is declared as just public and not public static, do i have to declare it as public static or is there any other chance to pass the specific property. Maybe by using a predicate?
That's the way it maybe could look like later?
public static IList<T> getList<T>(List<HeadStruct_Table> list, Func<HeadStruct_Table, T> getType)
{
var newList = new List<T>();
I just don't know how to get the special property and then, in the method, just read out those values. I wouldn't like to work with a string as parameter if it works without.
Anyone who has an idea?
That is my first question. I'm open for any advice to improve asking a question in here. Thank You.
LINQ's Enumerable.Select method already does what you want:
var newList = list.Select(x => x.colName).ToList();

Avoiding transposed parameters without creating coupling

I'm currently building a test application that manages parts for engineers, and I've hit a snag. I have a few different classes, including PartsModel and EngineerModel, and I want to update a list of parts that an engineer has, but I'm mindful of issues from either transposed parameters or from structuring the code in a way that unnecessarily couples to a particular class.
The two classes, with some relevant properties:
public class PartModel
{
public int PartId { get; private set; }
public string PartTitle { get; set; }
public string PartDescription { get; set; }
public int Quantity { get; set; }
public int MinimumStock { get; set; }
public void AddToStock (int quantityToAdd) {
Quantity += quantityToAdd;
}
public void RemoveFromStock (int quantityToRemove) {
Quantity -= quantityToRemove;
CheckMinimumStock();
}
}
public class EngineerModel
{
public int EngineerId { get; private set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<PartModel> PartsInStock { get; set; } = Factory.CreatePartsList();
}
As you can see, each engineer has a list of parts they have in stock via a List<PartModel>. I want to pass another list to this one so that I can update it respectively (incrementing or decrementing quantities, and then adding or removing parts to the list as necessary).
The first warning bell is that it takes two inputs of the same type, and is going to fill one from the other one (which isn't needed afterwards), so you're essentially modifying one input and destroying the other. To me, this presents a danger of the inputs getting transposed and the wrong list being either returned or updated (depending on whether it returns or just acts on the list). Because it removes items that have no quantity, it can't check the list length and just update the longer one, because there are possible cases where the engineer's list is shorter (maybe they're a new engineer, or maybe they just had a large shipment of parts sent when they were running low on stock). If it did just keep parts with quantity zero, then you're threatening scalability of both engineers and parts (not to mention any other objects that use the same operation).
So, put it as a method in the EngineerModel class and operate on PartsInStock, right? But what about when I want to use the same operation on other classes (e.g. if I have a list of parts associated to a work task)? Then I extract the method out to another class and... I'm passing the two lists as parameters in the method, so I'm back to where I was.
Am I being reasonable in not wanting to have two parameters of the same type, and how do I structure the code to deal with this, but without creating unnecessary coupling? If I'm not being reasonable, what am I overlooking?
Use an extension method
Thanks to #DavidBrowne-Microsoft for clarifying this. By defining an extension method for List<PartModel>, it only needs the one parameter - the list containing the updates (foreach below based on #Valentin's answer to this question).
public static class PartsHandler
{
public static List<PartModel> UpdateStockQuantitiesWith(this List<PartModel> stockToBeUpdated, List<PartModel> stockUpdates) {
foreach ( var part in stockUpdates )
{
var partToBeUpdated = stockToBeUpdated.FirstOrDefault(x => x.PartId == part.PartId);
if ( partToBeUpdated != null )
{ partToBeUpdated.Quantity += part.Quantity; }
else
{ stockToBeUpdated.Add(part); }
}
stockToBeUpdated.RemoveAll(x => x.Quantity <= 0);
return stockToBeUpdated;
}
}
Now any class that needs to implement this can simply call it in a method on the respective property. For example, in the EngineerModel class, it can operate on the PartsInStock property:
public void AddPartsToStock(List<PartModel> partsSent) {
PartsInStock.UpdateStockQuantitiesWith(partsSent);
}

Why and when should I use "this" to access methods from base class during inheritance in c#? [duplicate]

This question already has answers here:
When do you use the "this" keyword? [closed]
(31 answers)
Closed 3 years ago.
Noobie here, but I was wondering why and when would I need to use "this" keyword to access the Promote method in GoldenCustomer when I can already access it since GoldenCustomer is derived from the base class Customer which already has this method? Saw "this" being used in an online course but could't help but wonder.
Edit:
No my question isnt a duplicate because the other question doesnt answer when and if it is necessary to use "this" during inheritance.
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
customer.Promote();
GoldCustomer goldCustomer = new GoldCustomer();
goldCustomer.OfferVoucher();
}
}
public class GoldCustomer : Customer{
public void OfferVoucher(){
this.Promote(); //why is this used here?
}
}
public class Customer{
public int Id { get; set; }
public string Name { get; set; }
public void Promote(){
int rating = CalculateRating(excludeOrders: true);
if (rating == 0)
System.Console.WriteLine("Promoted to level 1");
else
System.Console.WriteLine("Promoted to level 2");
}
private int CalculateRating(bool excludeOrders){
return 0;
}
}
The most common uses is when a variable in a method/function has the same name as another class-level variable.
In this case, using the this keyword will tell the compiler that you're referring to the class's variable.
For example:
public class Customer
{
public string Name { get; set; }
Public Customer (string Name, string Id)
{
this.Name = Name; // "this.Name" is class's Name while "Name" is the function's parameter.
}
}
MSDN Doc for other uses and further reading
Also, a small side-note: ID should always be stored as a string since int has the maximum value of 2147483648, and ID's are treated as a string anyway (you never use math-related functions on it like Id++ or Id = Id * 2 for example).
I'm obviously referring to state-issued IDs like "6480255197" and not "1", "2" and so on.

Save class properties in a list

I have a class property called Instructions that I use to save my instructions data. I then save my Instruction class with the property to a list called _instructionList. Is this the best way to save my data which I can retrieve later or should I rather use another data structure like Tuple, ArrayList etc?
internal class Instructions
{
public string StreetName { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public string Kind { get; set; }
public double LengthInMeters { get; set; }
}
Put the data coming from ArrayList to the class property and save the class with his properties in the list.
public void SaveInstructions(ArrayList value)
{
_instructionList.Add(new Instructions {
StreetName = (string)value[0],
Latitude = (double)value[1],
Longitude = (double)value[2],
Kind = (string)value[3],
LengthInMeters = (double)value[4]
});
}
ArrayList is mostly used for compatibility with .NET 1.1. There's no reason to use it in new development.
Your question indicates that you're looking for a structure to contain the data for an instance of Instructions so that you can pass it to a method that will 1) create an instance of Instructions and 2) add it to a list.
But the structure you're looking for already exists - it's your Instructions class. Your method might as well look like this:
public void SaveInstructions(Instructions saved)
{
_instructionList.Add(saved);
}
That would be my first choice - create the instance separately and just call the method to add it to the class. That way SaveInstructions has a simpler purpose - to add to the list.
If you did want to pass the parameters (as in your question) then you might do this:
public void SaveInstructions(string streetName, double latitude,
double longitude, string kind, string lengthInMeters)
But that gets a little messy because the method has so many parameters. The first option is better because it doesn't require the method to "know" what all the properties of Instructions are.

How to store the output of method?

I am looking for easy way to store the output of the method in some sort of variable so that it can be used by another class.
For example:
partial class Form1 {
public string orderNumber() {
string ord="ORD"+get_next_id()+DateTime.Now.Year;
return ord;
}
}
In an instance of Form1 user enter the purchase details such as name, address... and when user clicks add entry button, the details is saved in the database with ordernumber generated by above code. In meantime when user click add entry, it kills the current form and bring up the another form which uses the ordernumber generated earlier. When I do like
Form1 m=new Form1();
and do something like(following is pseudo code)
m.orderNumber=string orderNUm.
It generates different order number which I don't want. I want to use the ordernumber that was saved in the database by the Form1.
I want to store that ord somewhere so that I can pass it to another class.
Another class can use the result simply by calling the method itself:
public class A
{
public string orderNumber()
{
string ord = "ORD" + get_next_id() + DateTime.Now.Year;
return ord;
}
}
public class B
{
public void DoSomeWork()
{
A a = new A();
string result = a.orderNumber();
}
}
The notion of "storing it somewhere" feels like the concept of a global variable. While one can accomplish essentially the same thing, that is to be discouraged as that does not represent object oriented design principals.
Just to understand how you could do that in C# (you should not do this), you could do:
static public SharedStorage
{
public string OrderNumber { get; set; }
}
// Somewhere in your code
SharedStorage.OrderNumber = a.orderNumber();
// Somewhere else in your code
string orderNumber = SharedStorage.OrderNumber;
If you want to set an order number on an instance once and then use it going forward, you could put the logic in the constructor:
public class A
{
public string OrderNumber { get; private set; }
public A()
{
OrderNumber = "ORD" + get_next_id() + DateTime.Now.Year;
}
}
// Somewhere else in your code
A a = new A();
string orderNumber = a.OrderNumber;
This is fairly basic stuff, but add this to the top of the class:
public string OrderCode;
Next add OrderCode = ord; above the return ord; line
Now whenever someone needs the ordercode they just make a call to <YourClass>.OrderCode
However, they could just call the method itself to get the order number as it is public.
PS: the orderNumber method doesn't follow c# conventions. a) it should be properly capitalized (OrderNumber) and b) a more meaningful name would be GetOrderNumber

Categories