c# need help working with arrays - c#

is there a way to put these into either a 1 D array or a 2 D array. ? i have produced code and it looks a bit untidy as well as long can this be shortened?
double worstPrice = 6.47;
double bestPrice = 0.99;
double CivetCatPrice =29.14;
double whenPrice = 10.50;
double everythingPrice = 319.56;
int bestStock = 3238;
int worstStock = 8;
int civetCatstock = 3;
int whenStock = 37;
int everythingStock = 2;

You can make an array for each doubles and ints like this
double[] priceData = new double[]{ 6.47, 0.99, 29.14, 10.50, 319.56 };
int[] stockData = new int[]{ 3238, 8, 3, 37, 2 };
Alternatively you can use a dictionary if you wish for them to keep their names
Dictionary<string, double> priceDict = new Dictionary<string, double>();
priceDict.Add("worstPrice", 6.47);
//And so on for each double
Dictionary<string, int> stockDict = new Dictionary<string, int>();
priceDict.Add("bestStock", 3238);
//And so on for each int
The values in these can be called like so
double worstMinusBestPrices = priceData[0] - priceData[1]; //For arrays
double worstMinusBestPrices = priceDict["worstPrice"] - priceDict["bestPrice"] //For dictionaries

You could implement a custom class which holds these values as proprties with meaningful names. Then your code will be much more readable, maintainable and robust.
For example (you don't need all of these classes, it should just give you an idea):
public abstract class Animal
{
public Animal(string animalName)
{
this.Name = animalName;
}
//insert properties and methods which all aimals share here
public string Name { get; set; }
}
public class CibetCat : Animal
{
public CibetCat() : base("CibetCat")
{
}
//insert properties and methods which all CibetCats share here
}
Now your class that holds the price and stock informations as well as the reference to the animal itself(CibetCat in your example):
public class AnimalStock // or AnimalPrice or whatever
{
public AnimalStock(Animal animal)
{
this.Animal = animal;
}
public AnimalStock(Animal animal, decimal worstPrice, decimal bestPrice, int bestStock, int worstStock)
{
this.Animal = animal;
this.Worstprice = worstPrice;
this.BestPrice = bestPrice;
this.BestStock = bestStock;
this.WorstStock = worstStock;
}
public Animal Animal { get; set; }
public decimal Worstprice { get; set; }
public decimal BestPrice { get; set; }
public int BestStock { get; set; }
public int WorstStock { get; set; }
// ...
}
Lot of code but not complex. Now You can write this simple and readable code:
Animal cibetCat = new CibetCat();
AnimalStock stock = new AnimalStock(cibetCat);
stock.BestPrice = 0.99m;
stock.Worstprice = 6.47m;
stock.BestStock = 3238;
// ...
Later you can access all these properties(or it's methods) from a single instance.
Console.WriteLine("Animal's best-price is: {0}", stock.BestPrice); // etc

As Alfie pointed out, you could use a dictionary - but you're then referencing things by a string identifier, that you have to remember.
Another way would be to use a class or struct. There are of course many ways to do this, but some include:
public class Things
{
public double worstPrice = 6.47;
public double bestPrice = 0.99;
public double CivetCatPrice =29.14;
public double whenPrice = 10.50;
public double everythingPrice = 319.56;
public int bestStock = 3238;
public int worstStock = 8;
public int civetCatstock = 3;
public int whenStock = 37;
public int everythingStock = 2;
}
Another way would be:
public class Things
{
public double WorstPrice { get; readonly set; }
public double BestPrice = { get; readonly set; }
// etc
public Things(double worstPrice, double bestPrice) // etc
{
WorstPrice = worstPrice;
BestPrice = bestPrice;
}
}
There are pros and cons to both approaches. Another potential is to use a collection of a class/struct to group things and aggregate them in meaningful ways.
Like:
public class Thing
{
public string ThingLabel { get; readonly set; }
public double ThingPrice { get; readonly set; }
public int ThingQuantity { get; readonly set; }
// the value of your stock, calculated automatically based on other properties
public double ThingValue { get { ThingPrice * ThingQuantity; } }
public Thing(string thingLabel, double thingPrice, int thingQuantity)
{
ThingLabel = thingLabel;
// etc
}
}
public void DoStuff()
{
List<Thing> list = new List<Thing>();
Thing thing = new Thing("Civet cat", 500, 10);
list.Add(thing);
list.Add(new Thing("Sea flap flap", 100, 5);
list.Add(new Thing("Nope Rope", 25, 4);
Console.WriteLine("The value of {0}'s stock is: {1}", thing.ThingLabel, thing.Value);
}
and yet another way is to use a base class and create sub classes of your different types. The possibilities are nearly endless! You just have to decide which way works best for you now, you later, and your potential team.

Related

Loop through a list of objects and print

I'm making an attempt at looping through Course objects and displaying them to the console. For some reason however my solution doesn't seem to work, can anyone detect any obvious issues that I might be the cause for this? thanks :)
class Course
{
private int v1;
private string v2;
private string v3;
private int v4;
public Course(int v1, string v2, string v3, int v4)
{
this.v1 = v1;
this.v2 = v2;
this.v3 = v3;
this.v4 = v4;
}
public int courseCode { get; set; }
public string courseName { get; set; }
public string professor { get; set; }
public int capacity { get; set; }
}
class Computation
{
public static List<Course> courses = new List<Course>();
public static void addCourse(Course c)
{
courses.Add(c);
}
public static void viewCourses()
{
foreach(var c in courses)
{
Console.WriteLine(c.courseName);
}
}
}
Main
static void Main(string[] args)
{
Course computerScience = new Course(1, "Computer Science", "Dr Shkhla", 200);
Course mathematics = new Course(2, "Mathematics", "Dr Shkhla", 200);
Course physics = new Course(3, "Physics", "Dr Shkhla", 200);
addCourse(computerScience);
addCourse(mathematics);
addCourse(physics);
viewCourses();
}
The problem is that you are never assigning anything to those properties. Also, it is a very good time to learn standard naming conventions:
public class Course
{
public Course(int code, string name, string professor, int capacity)
{
Code = code;
Name = name;
Professor = professor;
Capacity = capacity;
}
// properties should be in PascalCase
// and should not have their entity's name as prefix
public int Code { get; set; }
public string Name { get; set; }
public string Professor { get; set; }
public int Capacity { get; set; }
}
Names that are sequences (v1, v2, etc in your code) should be avoided most of the times.
Also, notice that I deleted the unused properties from the class.
Change your constructor to:
public Course(int courseCode, string courseName, string professor, int capacity)
{
this.courseCode = courseCode;
this.courseName = courseName;
this.professor = professor;
this.capacity = capacity;
}
You need to update your constructor:
public Course(int v1, string v2, string v3, int v4)
{
courseCode = v1;
courseName = v2;
professor = v3;
capacity = v4;
}
or set your properties directly:
Course computerScience = new Course
{
courseCode = 1,
courseName = "Computer Science",
professor = "Dr Shkhla",
capacity = 200
};
If you like to have an nicer console output, override your toString() function of the Course model.
public override string ToString()
{
return $"Course {courseCode}: {courseName} by {professor}. Capacity: {capacity}";
}

C# - declare constant fields, but organize with interface?

I have a bunch of constant values for several types of "buildings", the sizes of which are fixed (due to the 3D model they will hold).
I've looked around and read about base classes, interfaces and abstracts, but couldn't really grasp the concepts completely. However I really liked the idea of using interfaces to "organize" classes with common fields. In this case, sizeX and sizeY is a type of field shared across all building classes.
public static class BuildingProperties {
public class House
{
public const int sizeX = 4;
public const int sizeY = 4;
}
public class House1
{
public const int sizeX = 6;
public const int sizeY = 6;
}
public class Commercial
{
public const int sizeX = 10;
public const int sizeY = 10;
}
}
Is there some way I can implement an interface for this, without the need for constructors in each class? (I would like to simply call for these constants as required, like so:)
public void program()
{
int sizeX = BuildingProperties.House.sizeX;
}
And for future use, if I needed to add another field (for example "height"), I would like the compiler to throw an error and say "hey! you forgot to give House1 a "height" value!
Is there something like this that someone can point me towards?
Seems to me like your code need some re-design. I don't see why you would want to have all these public sub classes. Instead, I would just use one class for all building types (assuming the all always have the same properties) and 3 properties for that class's type:
public class Building
{
public Building(int sizeX, int sizeY)
{
SizeX = sizeX;
SizeY = sizeY;
}
public int SizeX { get; }
public int SizeY { get; }
}
public static class BuildingProperties
{
public static Building House { get; } = new Building(4, 4);
public static Building House1 { get; } = new Building(6, 6);
public static Building Commercial { get; } = new Building(10, 10);
}
Note that all the properties are immutable in this code sample, and also, if you add a property in the future, and would like to get compiler errors when it's missing, all you have to do is change the constructor of the Building class to acccept another parameter for this new readonly property.
You can simply create an interface that will declare 2 getter properties:
public interface IProvideSizes
{
int SizeX { get; }
int SizeY { get; }
}
And in your classes have them return the data from your const:
public class House : IProvideSizes
{
public const int _sizeX = 4;
public const int _sizeY = 4;
public int SizeX { get { return _sizeX; } }
public int SizeY { get { return _sizeY; } }
}
public class House1 : IProvideSizes
{
public const int _sizeX = 6;
public const int _sizeY = 6;
public int SizeX { get { return _sizeX; } }
public int SizeY { get { return _sizeY; } }
}
public class Commercial : IProvideSizes
{
public const int _sizeX = 10;
public const int _sizeY = 10;
public int SizeX { get { return _sizeX; } }
public int SizeY { get { return _sizeY; } }
}
This way you can preserve and maintain the contract of each type, while still being able to access each type's specific size in a static way (without the need to instantiate it).
Have you considered a dictionary?
Dictionary<string, System.Drawing.Point> properties = new Dictionary<string, System.Drawing.Point>() {
{"House", new System.Drawing.Point(4,4)},
{"House1", new System.Drawing.Point(6,6)},
{"Commercial", new System.Drawing.Point(10,10)}
};

c# How to access elements of a list of objects consisting of int and string in foreach

I have a list of objects of a class, made of a string and an int.
public class PatternInfo
{
private string prpatternname;
private int prpatterntier;
public PatternInfo(string patternname, int patterntier)
{
prpatternname = patternname;
prpatterntier = patterntier;
}
}
This is in a seperate file.
I have a list of such objects:
public List<PatternInfo> patternlist;
Now for each obejct of this class in a list, I want to set values of variables to those two values:
foreach (PatternInfo x in patternlist)
{
string a = patternname;
int b = patterntier;
}
for some reason I get "the name patternname/patterntier does not exist in current context". I have tried playing with some solutions, but can't get it to work, please help :)
To align with OP:
public class PatternInfo
{
public string prpatternname { get; }
public int prpatterntier { get; }
public PatternInfo(string patternname, int patterntier)
{
prpatternname = patternname;
prpatterntier = patterntier;
}
}
As you haven't provided how you declare patternlist, I made up the following:
public static void Main()
{
List<PatternInfo> patternlist = null;
for (int i = 0; i < 10; i++)
patternlist.Add(new PatternInfo(i.ToString(), i));
foreach(PatternInfo x in patternlist)
{
string a = x.prpatternname;
int b = x.prpatterntier;
}
}
This is because the attributes are private and attributes of x. Add this to a PatternInfo:
public string name { get;}
public int tier {get;}
Then, in the loop, you can have the following:
string a = x.name;
int b = x.tier;

Get the index in a multidimensional class

Sorry for the title i will put here an example of what i want to accomplish:
namespace mdclass
{
class pClass
{
static void Main()
{
tiles<int> tl = new tiles<int>();
tl[0].X = 0;
}
}
class tiles<T> : List<T>
{
public int X
{
//get/set the X-coordonate
}
public int Y
{
//get/set the Y-coordonate
}
}
}
how can i transfer the [0] from the tl[0] in the public int X and work with it?
Create a class for x and y coordinates:
public sealed class Point {
public int X { get; set; }
public int Y { get; set; }
}
Use the Point class to store the coordinates into the list:
public sealed class Program {
public static void Main() {
var tiles = new List<Point>();
tiles.Add(new Point { X = 5, Y = 10 });
tiles[0].X = 15;
}
}
Could you not just make tl public?
Then myInt = mypClass.tl[0].X
A data heirachy like this might work for you (no time to add actual code, sorry!). Then you could implement appropriate getters and setters.
Public class Grid {
List<Row>
}
Public class Row{
List<Point>
}
Public Class Point{
public int X { get; set; }
public int Y { get; set; }
}

ordering generic list by size property

Hi I have had to use interfaces before but ive been told i need to implement icomparable in this instance. see below:
internal class doorItem : IComparable
{
public int CompareTo(doorItem other)
{
// The temperature comparison depends on the comparison of the
// the underlying Double values. Because the CompareTo method is
// strongly typed, it is not necessary to test for the correct
// object type.
return GetNumber(productSize).CompareTo(GetNumber(other.productSize));
}
public string variations { get; set; }
public double pricerange { get; set; }
public string viewDetailsLink { get; set; }
public string height { get; set; }
public string width { get; set; }
public string productSize { get; set; }
public string productImage { get; set; }
public int countItemsOnSale { get; set; }
public string optionFor35Product { get; set; }
private int GetNumber(string str)
{
//this method gets the int out of the string
int length = str.Length;
string output = String.Empty;
int test = 0;
bool err = false;
for (int i = 0; i <= length; i++)
{
try
{
test = Convert.ToInt32(str.Substring(i, 1));
}
catch
{
err = true;
}
if (!err)
output += str.Substring(i, 1);
else
break;
}
return Convert.ToInt32(output);
}
}
above is the class i have created, door sizes are returned like this: 4dr, 5dr, 6dr etc.. then the getnumber method gets the int out of the string.
i have a generic list in of my custom class in the main method like this:
List<doorItem> d = new List<doorItem>();
i cant work out how to order this list by door size.... PLEASE HELP
It's easiest to do this using LINQ. Then you don't even need to implement IComparable.
var sortedList = doorList.OrderBy( d => d.GetNumber(d.productSize ).ToList();
And make GetNumber public inside the doorItem class.
I don't know if performance is important, but that method for getting the number is pretty horrible, exceptions should only be used in exceptional circumstances! Suggest something like this
StringBuilder sb = new StringBuilder();
foreach (char c in str)
{
if (Char.IsNumber(c))
{
sb.append(c);
}
}
return Convert.ToInt32(sb.ToString());
For sorting you can do what stecya has suggested, or you could convert this method to a property and sort directly.
public int Size
{
get
{
return GetNumber(this.productSize);
}
}
...
d.OrderBy(x=>x.Size);

Categories

Resources