The idea is simple. Make a struct for "Departments" of a store, give it a variable for naming (a string called "Department"), and a array to save all buys done in that department.
Now, I want that every time that I'm gonna save a buy on a specific Department, it auto-applies a discount based on department's name and buy amount.
Now, the example class:
class Program
{
struct Departments
{
public string Department;
private double[] _buys;
public double[] Buys
{
get { return _buys; }
set
{
if (value > 100)
{
if (Department == "CLOTH")
_buys = value * .95;
if (Department == "FOOD")
_buys = value * .90;
if (Department == "OTHER")
_buys = value * .97;
}
_buys = value;
}
}
}
static void Main()
{
var departments = new Departments[3];
departments[0].Department = "CLOTH";
departments[1].Department = "FOOD";
departments[2].Department = "OTHER";
departments[0].Buys = new double[5];
departments[0].Buys[0] = 105;
}
}
Note the line departments[0].Buys[0] = 105
, that's the way that I want to save bought things, "Code-Simple"...
Now, note the property Buys
of the struct, it's an "Array Property". Then, when I use the value > 100
condition it gives an obvious error, can't cast from double
to double[]
.
The question... how can I write a right condition for value > 100
, what else must be put on the stuct to achieve this?
I've tried with "Indexers", but as long as I've tried I can't make it take assignemts via departments[0].Buys[0] = 105
in the right way.
Please note that I wanna keep this schema, specially for the facility of simply say departments[0].Buys[0] = 105
to asing buyings
EDIT:
The previous struct "Departments" is done for example-purposes only. I won't answers about making it by another way to have right "Departments", I want an answer of how to make the set parameter work on individual elements of arrays
One more potential solution is to make another class for the _buys array:
class Buys
{
private double[] _buys;
public Buys (int capacity)
{
_buys = new double[capacity];
}
public double this[int index]
{
get { return _buys; }
set
{
if (value > 100)
{
if (Department == "CLOTH")
value = value * .95;
if (Department == "FOOD")
value = value * .90;
if (Department == "OTHER")
value = value * .97;
}
_buys = value;
}
}
}
struct Departments
{
public string Department;
public Buys Buys;
}
static void Main()
{
var departments = new Departments[3];
departments[0].Department = "CLOTH";
departments[1].Department = "FOOD";
departments[2].Department = "OTHER";
departments[0].Buys = new Buys(5);
departments[0].Buys[0] = 105;
}
Department
can't be accesed on Buys class. I changed the thing and applied inheritance, so, now I'm using classes and not structs - mishamosher 2012-04-05 04:01
You'd be better off using a List<double>
to record the purchases. That way the list can grow dynamically. You can also use indexes to get the list elements.
You can simplify the discount code using a dictionary.
For this data you'd also be better off using a class
, rather than a struct
. Struct
s are generally better used for immutable values. Make the class represent a single department and store the appropriate discount in it.
So something like this:
class Program
{
class Department
{
public string Name;
public double Discount;
private List<double> _buys = new List<double>();
public List<double> Buys
{
get { return _buys; }
}
public void AddBuy(double value)
{
_buys.Add(value > 100 ? value * discount : value);
}
}
static void Main()
{
var departments = new List<Department>();
departments.Add(new Department { Name = "CLOTH", Discount = 0.95 });
departments.Add(new Department { Name = "FOOD", Discount = 0.90 });
departments.Add(new Department { Name = "OTHER", Discount = 0.97 });
departments[0].AddBuy(105);
Console.WriteLine(departments[0].Buys[0]);
}
}
There are many other ways I'd improve this design, but this should get you going.
you could do something like this
public class Departments
{
public string Department;
public MyList buys;
public Departments()
{
buys = new MyList(this, 5);
}
}
public class MyList
{
private double[] backingList;
private Departments owner;
public MyList(Departments owner, int size)
{
this.owner = owner;
backingList = new T[size];
}
public double this[int index]
{
get{ return backingList[index]; }
set { backingList[index] = discountFor(owner.Department) * value; }
}
private float discountFor(string department)
{
switch(department)
{
case "department1":
return 0.5f;
//...
default:
return 1.0f;
}
}
}
However you are not maintaining good separation of concerns by putting the discount into the setter its self. Better code would look something like
departments[0].Buys[0] = DiscountFor("department1") * 105;
By your error you can do something like this.
struct Departments
{
public string Department;
private double[] _buys;
public double[] Buys
{
get { return _buys; }
set
{
for (int i = 0; i < value.Length; i++)
{
if (value[i] > 100)
{
if (Department == "CLOTH")
_buys[i] = value[i] * .95; if (Department == "FOOD")
_buys[i] = value[i] * .90; if (Department == "OTHER")
_buys[i] = value[i] * .97;
}
}
_buys = value;
}
}
}
for
loop it will retouch all the _buys stored previusly... a way of make this avoiding that - mishamosher 2012-04-05 03:12
You could create a method to do the setting like this:
public double[] Buys { get; set; }
public void SetBuy(int index, double value)
{
if (value > 100)
{
if (Department == "CLOTH")
value = value * .95;
if (Department == "FOOD")
value = value * .90;
if (Department == "OTHER")
value = value * .97;
}
_buys[index] = value;
}
Structs which contain mutable references to mutable items are generally a bad idea, since such structures end up exhibiting a weird combination of value and reference semantics. For example, what should be the effect of:
Departments dep1,dep2; ... dep1 = dep2; dep1.Department = "CLOTH"; dep1.Buys[5] = 123;
It's hardly obvious that such a statement will or should affect dep2.Buys[5]
. If a given structure's Buys
field/property would always refer to the same array, such semantics might be tolerable, but what happens if the array needs to be resized?