I have created an Inventory Class but I don't know how to retrieve information from it. I know how to go over it in a foreach loop and display all items, but I don't know how to see if YoYo is in there and if it is, print the Name, Cost and Quantity to a label. Can anybody please help?
I hope you're going beyond an Inventory class and creating a Product class as well. Object-oriented languages are all about encapsulation and information hiding. Embed the output of the Product in a method for that object. Clients can simply call it that way instead of having to repeat it all over the place.
I'd also recommend a find method in your Inventory class that lets you search for a Product instance. You might want to search by name now, but what about cost, category, or manufacturer? Perhaps you'll want to extend it later.
I agree with Marc's dictionary recommendation, but I would advise that you made that part of Inventory's private implementation. You're adding an extra bit of abstraction that makes an Inventory something more than a mere dictionary.
I think strings and data structures are wonderful, but too often these primitives leak into code when hiding them in an object would be much better for clients. That's what I think good object-oriented design is all about.
Since you mention foreach, it sounds like it implements IEnumerable<T>. In which case, if you are using C# 3.0 / LINQ, something like:
var yoyo = inventory.FirstOrDefault(item => item.Name == "YoYo");
if(yoyo != null) { // found it
Console.WriteLine(yoyo.Cost); // etc
}
You might also look at dictionaries if you have a lot of data...
Related
This is for c#
I'm an old dinosaur, writing 360 assembler since the 70's, trying to write stuff for the PC. Along the way I am replacing my old write it myself thinking with use the existing infrastructure.
Here is what I have now. Two objects, System and Planet. A field in System has a pointer to the next System, there is also a second chain of Systems that meet current selection criteria. Also System has a pointer to Planet and Planet has a pointer to the next Planet. Planet also has a chain of all planets.
Now the questions. Should I use lists and have C# handle all the linking etc. I'm fairly sure 1 object instance can be in multiple lists, so I can have 1 list of all systems and a second list of selected systems. Plus have a list of Planets in the system and another list of all Planets.
I also want to save this mess to disk. I've spent some time looking at serialization and it appears to be great at saving all the instances in a list, but things break down when you want to serialize multiple classes. Am I missing something basic, just a yes will send me back to looking, or do I have to roll my own?
I don't want code examples, just a gentle puch in the direction I should be looking at.
I would simply create two classes, one being the System with a List<Planet> containing all its planets and the other one being the Planet, containing a reference to his system (if one is required). The systems are themselves saved in a List<System>. Like the planets they could hold a reference to their parent so they have access to the list, but if they don't need to, its fine.
Saving this stuff should be three lines of code with a serializing system of your choice, either in text or binary (Json.Net, the Xml stuff .Net provides, yaml, binary formatter...).
Linked lists are not worth the implementation, they aren't as useful as dynamic arrays (like the List<T> in System.Collections.Generic or the Vector<T> in C++) which resize themselves when needed, and they aren't that easy to keep track of. They definetly have applications but this is not one of them IMO.
Should I use linked list or list...
The answer depends on what your object represents and how you are going to use it. For example, if I was representing houses, and the people who live at each house; then I might choose to have a collection of House objects. I'm using collection as a generic term there: specifically, I would probably use List<T> from the System.Collections.Generic namespace (where T can represent any type, so it would be a List<House> in this case), unless I needed something more specific like a Stack<T>, Queue<T>, Dictionary<T,U>, etc, etc.
Notice how in this approach, each House doesn't know which house is next, because the whole concept of 'next' relates to the collection of houses: each individual house doesn't need to know where it is in the collection - that's the responsibility of the collection. This is a design principle called "separation of concerns".
For example, if I wanted to create a different collection of House objects (e.g. the ones with red front doors), I could do so by creating a new collection, referring to the same House objects; whereas with the approach mentioned of an object having a reference to the next one, I would have to create a different House object because the next value would be different in those two collections.
Using List<T> allows you to focus on writing your classes, instead of having to write the implementation of the collection.
There are also performance reasons against using linked lists unless you only plan to access the data in sequential order.
Each House has-a collection of people. So I might put a property on House called People, of type List<Person>. And if I needed to get to the house that the person was associated with, I could have a property on Person called House, of type House.
I hope this structure of Houses and People corresponds to your scenario with Systems and Planets.
Maybe also worth looking at When should I use a List vs a LinkedList
...and how do I serialize it.
Plenty on the internet, try these...
How to Serialize List<T>?
https://www.thomaslevesque.com/2009/06/12/c-parentchild-relationship-and-xml-serialization/
Hope this helps to get you started.
From the sound of it, I will create class of System, Planet with one to many reference of planets in System (List here). In order to avoid strong coupling between System and Planet, One can look at Chain of Responsibility pattern.
Saving this data to database one can serialise using Json.Net (newtonsoft). SQL server supports directly putting json array.
Pseudo code:
class Planet {
public Planet(System system) {System = system;}
public System System {get; private set;} // singleton
}
class System {
public Planet Planet {get; set;}
// list of planets
private List<Planet> planets = new List<Planet>();
public List<Planet> Planets { get {return planets; } }
}
I have a (not quite valid) CSV file that contains rows of multiple types. Any record could be one of about 6 different types and each type has a different number of properties. The first part of any row contains the timestamp and the type of record, followed by a standard CSV of the data.
Example
1456057920 PERSON, Ted Danson, 123 Fake Street, 555-123-3214, blah
1476195120 PLACE, Detroit, Michigan, 12345
1440581532 THING, Bucket, Has holes, Not a good bucket
And to make matters more complex, I need to be able to do different things with the records depending on certain criteria. So a PERSON type can be automatically inserted into a DB without user input, but a THING type would be displayed on screen for the user to review and approve before adding to DB and continuing the parse, etc.
Normally, I would use a library like CsvHelper to map the records to a type, but in this case since the types could be different, and the first part uses a space instead of comma, I dont know how to do that with a standard CSV library. So currently how I am doing it each loop is:
String split based off comma.
Split the first array item by the space.
Use a switch statement to determine the type and create the object.
Put that object into a List of type object.
Get confused as to where to go now because i now have a list of various types and will have to use yet another switch or if to determine the next parts.
I don't really know for sure if I will actually need that List but I have a feeling the user will want the ability to manually flip through records in the file.
By this point, this is starting to make for very long, confusing code, and my gut feeling tells me there has to be a cleaner way to do this. I thought maybe using Type.GetType(string) would help simplify the code some, but this seems like it might be terribly inefficient in a loop with 10k+ records and might make things even more confusing. I then thought maybe making some interfaces might help, but I'm not the greatest at using interfaces in this context and I seem to end up in about this same situation.
So what would be a more manageable way to parse this file? Are there any C# parsing libraries out there that would be able to handle something like this?
You can implement an IRecord interface that has a Timestamp property and a Process method (perhaps others as well).
Then, implement concrete types for each type of record.
Use a switch statement to determine the type and create and populate the correct concrete type.
Place each object in a List
After that you can do whatever you need. Some examples:
Loop through each item and call Process() to handle it.
Use linq .OfType<{concrete type}> to segment the list. (Warning with 10k
records, this would be slow since it would traverse the entire list for each concrete type.)
Use an overridden ToString method to give a single text representation of the IRecord
If using WPF, you can define a datatype template for each concrete type, bind an ItemsControl derivative to a collection of IRecords and your "detail" display (e.g. ListItem or separate ContentControl) will automagically display the item using the correct DataTemplate
Continuing in my comment - well that depends. What u described is actually pretty good for starters, u can of course expand it to a series of factories one for each object type - so that you move from explicit switch into searching for first factory that can parse a line. Might prove useful if u are looking to adding more object types in the future - you just add then another factory for new kind of object. Up to you if these objects should share a common interface. Interface is used generally to define a a behavior, so it doesn't seem so. Maybe you should rather just a Dictionary? You need to ask urself if you actually need strongly typed objects here? Maybe what you need is a simple class with ObjectType property and Dictionary of properties with some helper methods for easy typed properties access like GetBool, GetInt or generic Get?
I have a regular C# class called "vehicle" with properties like Name, NumberPlate, MaxSpeed, etc.
All the data for the class is stored in a SQLite Database where I have a Table "Car" and "Boat". The tables colums have the same names as the class properties (however, there are more columns than class properties - vehicle is a more generic abstraction). At the moment, I have to assign the result of the query individually one by one like this:
while (await statement.StepAsync())
{
myVehicle.Name = statement.Columns["Name"];
//[...]
myVehicle.MaxSpeed = decimal.TryParse(statement.Columns["MaxSpeed"]);
}
Additionally, I have to check if some columns exist ("Car" and "Boat" have a different set of columns) which is more code than I'd like it to be.
I read about EntityFramework to map my db table to my class - but that seems overkill. My requirement is to map properties and columns that have the same name and ignore everything else.
Is there a "easy" (dev time, lines of code) way to map my table columns to my class?
Thanks for reading!
The restrictions in phone 8 mean that a lot of the standard answers to this ("just use {some ORM / micro-ORM}") won't apply, since they don't work on phone 8. You can probably use reflection for a lot of this, but: reflection can be (relatively) slow, so it depends on how much data you will be processing. If it is occasional and light: fine, reflect away.
Runtime meta-programming (the tricks used by libraries like "dapper" in full .NET to make these things really fast) is not available on restricted runtimes, so if you want to avoid lots of boiler-plate that leaves build-time meta-programming. At the simplest, I wonder if you could use something like T4 to automate creating these methods for you as C#. There are also ways to use the reflection-emit API to construct assemblies (at build-time) for phone 8, but that is a pretty hard-core route.
My thoughts:
if the amount of types here isn't huge, just write the code
if you have a lot of types, or you just feel like it, consider a build-time code-generation meta-programming step; you might even think "hmm, is this something I could make available to the community?"
of course, the first thing to do is to check that such a thing doesn't already exist
There is a little helper which might fit your case. Basically, it will take a dictionary and try it's best to populate a objects properties using reflection. I didn't try it by myself though.
You'd simply do something like:
while (await statement.StepAsync())
{
myVehicle = DictionaryToObject<Car>(statement.Columns);
}
It might need some further work to get it running but maybe a good start.
I have a table in my database called "OrderItemType" which has about 5 records for the different OrderItemTypes in my system. Each OrderItem contains an OrderItemType, and this gives me referential integrity. In my middletier code, I also have an enum which matches the values in this table so that I can have business logic for the different types.
My dev manager says he hates it when people do this, and I am not exactly sure why. Is there a better practice I should be following?
I do this all the time and I see nothing wrong with this. The fact of the matter is, there are values that are special to your application and your code needs to react differently to those values. Would your manager rather you hard-code an Int or a GUID to identify the Type? Or would he rather you derive a special object from OrderItem for each different Type in the database? Both of those suck much worse than an enum.
I don't see any problem in having enum values stored in the database, this actually prevents your code from dealing with invalid code types. After I started doing this I started to have fewer problems, actually. Does your manager offer any rationale for his hatred?
We do this, too. In our database we have an Int column that we map to an Enum value in the code.
If you have a real business concern for each of the specific types, then I would keep the enum and ditch it in the database.
The reason behind this approach is simple:
Every time you add an OrderType, you're going to have to add business logic for it. So that justifies it being in your business domain somewhere (whether its an enum or not). However, in this case having it in the database doesn't do anything for you.
I have seen this done for performance reasons but I think that using a caching mechanism would be perferable in most cases.
One alternative to help with the synchronization of the database values and the business logic enum values would be to use the EnumBuilder class to dynamically generate a .dll containing the current enum values from the database. Your business logic could then reference it, and have intellisense-supported synchonized enum values.
It's actually much less complicated than it sounds.
Here's a link to MSDN to explain how to dynamically build the enum.
http://msdn.microsoft.com/en-us/library/system.reflection.emit.enumbuilder.aspx
You just have to sub in the database access code to grab the enum values:
One more vote for you, I also use mapping database int <-> application enum, in addition, I usually describe my enums like this:
public enum Operation
{
[Description("Add item")]
AddItem = 0,
[Description("Remove item")]
RemoveItem = 1
}
which leaves me absolutely free to add new values without need to change database and with a very short workaround I can work i.e. with lists containing descriptions (that are very strongly tied to values!) - just a little bit of reflection reaches the goal!
In code, you can typically just add a property like this:
public class Order
{
public int OrderTypeInt;
public OrderTypeEnum OrderType
{
get { return (OrderTypeEnum)OrderTypeInt; }
set { OrderTypeInt = (int)value; }
}
}
I'm currently having a problem with a ShoppingCart for my customer.
He wants to be able to add Text between the CartItems so I was wondering if there is some way to still only have one List.
My solution would be to have two lists, one of type IList that gets iterated over when calculating Weight and overall Price of the Cart while having another IList that only exposes the necessary fields for displaying it in the ListView and that is a SuperType of CartItem. (But how do I then access additional fields for the listView, defaulting weight and price to 0 in the Description-Text-Class would break LSP).
But having two lists somehow feels a bit odd (and still gives me problems), so I was wondering if I could do some sort of a TypedList where I specify the Type of each item.
Any suggestions are welcome, I'm not really happy with both options.
Use an interface:
ICartListItem
And make your list be:
List<ICartListItem>
Now, create several types, have all of them implement this interface, and you can store them all safely in your list.
Alternatively, if you want there to be some default logic in a CartItem, use a base class instead of an interface.
You can make a class and, inside of that, define the properties of the required list type and then make a list of same class.
For example, if I wanted to make a list of strings and bools, I would make two properties in one class and then make a list of that class.
The Interface sounds like overkill. I'd just add a property to your current CartItem named something like "TextAfterItem".
Also: make sure your customer understands the cost of this feature in terms of security overhead. It sounds like they think this should be a simple update, but you're allowing users to enter text that will be displayed directly back to the page, and that's a dangerous proposition.