So I'm completely new to programming; I've read the many similar questions and respective answers on here, and spent more time than I'd like to admit trying different ways of solving my problem, but I can't seem to find where the problem lies. Anyway, here's my code:
public struct City
{
public string cityName { get; set; }
public float cityTemp { get; set; }
}
class Program
{
static void Main(string[] args)
{
var cityList = new List<City>();
cityList.Add(new City
{
cityName = "Stockholm",
cityTemp = 22.65f
});
Console.WriteLine("List: ");
Console.WriteLine(cityList);
Console.ReadKey();
}
}
How do I make the list store my structs and how do I display the list properly?
Edit: I know I need to use foreach, this code was just a barebones representation of my problem.
You want something like this:
public struct City
{
public string cityName { get; set; }
public float cityTemp { get; set; }
}
class Program
{
static void Main(string[] args)
{
var cityList = new List<City>();
cityList.Add(new City
{
cityName = "Stockholm",
cityTemp = 22.65f
});
cityList.Add(new City
{
cityName = "London",
cityTemp = 25.24f
});
Console.WriteLine("List: ");
foreach (var city in cityList)
{
Console.WriteLine(string.Format("City: {0} is currently: {1}oC", city.cityName, city.cityTemp);
}
Console.ReadKey();
}
}
You could also make your city output a sensible response by overriding ToString() like this:
public struct City
{
public string cityName { get; set; }
public float cityTemp { get; set; }
public override string ToString()
{
return String.Format("City: {0} is currently: {1}oC", cityName, cityTemp);
}
}
So then you could have:
class Program
{
static void Main(string[] args)
{
var cityList = new List<City>();
cityList.Add(new City
{
cityName = "Stockholm",
cityTemp = 22.65f
});
cityList.Add(new City
{
cityName = "London",
cityTemp = 25.24f
});
Console.WriteLine("List: ");
foreach (var city in cityList)
{
Console.WriteLine(city);
}
Console.ReadKey();
}
}
The list is storing your structs. As for displaying them, that doesn't work by magic. You'll have to loop over the list and display each one.
public struct City
{
public string cityName { get; set; }
public float cityTemp { get; set; }
public override string ToString()
{
return String.Format("{0} {1}", cityName, cityTemp);
}
}
public void DisplayAll(IEnumerable<City> cities)
{
foreach (var city in cities)
Console.WriteLine(city);
}
You need to loop over your list of cities to display them:
Console.WriteLine("List: ");
foreach(var city in cityList)
{
Console.WriteLine(city.cityName + " " + city.cityTemp);
}
Related
I am doing an assignment where you make a distribution company and have to add/remove food and chemical items from the company ledger. I wrote the add sections through generics but I am having difficulties with the remove part. I do not know how to write the logic for the remove items part where the user enter an item to remove and then if it matches it will remove it.
{
class Product : Food, Cleaner
{
public string food { get; set; }
public string cleaner { get; set; }
public string foodRemover { get; set; }
public string cleanerRemover { get; set; }
public void GenericMethod<T>(T param)
{
Console.WriteLine();
}
public class Food<T>
{
public T food { get; set; }
public T doFood (T f)
{
return f;
}
}
public class Cleaner<T>
{
public T cleaner { get; set; }
public T doCleaner(T c)
{
return c;
}
}
public void addFood()
{
Console.WriteLine("Food:");
Food<string> food1 = new Food<string>();
Console.Write(food1.doFood("Pizza"));
Food<int> food1index = new Food<int>() { food = 1 };
Console.Write(food1index.doFood(1));
Console.WriteLine();
Food<string> food2 = new Food<string>();
Console.Write(food2.doFood("Pasta"));
Food<int> food2index = new Food<int>() { food = 2 };
Console.Write(food2index.doFood(2));
Console.WriteLine();
Food<string> food3 = new Food<string>();
Console.Write(food3.doFood("Sushi"));
Food<int> food3index = new Food<int>() { food = 3 };
Console.Write(food3index.doFood(3));
Console.WriteLine();
}
public void removeFood(Food removeFood)
{
Console.WriteLine("Enter food name you want to remove");
foodRemover = Console.ReadLine();
if (foodRemover == )
{
}
}
public void addCleaner()
{
Console.WriteLine("Cleaners:");
Cleaner<string> cleaner1 = new Cleaner<string>();
Console.Write(cleaner1.doCleaner("Baking soda"));
Cleaner<int> cleanerindex1 = new Cleaner<int>();
Console.Write(cleanerindex1.doCleaner(1));
Cleaner<string> cleaner2 = new Cleaner<string>();
Console.Write(cleaner2.doCleaner("Mouth wash"));
Cleaner<int> cleanerindex2 = new Cleaner<int>();
Console.Write(cleanerindex2.doCleaner(2));
Cleaner<string> cleaner3 = new Cleaner<string>();
Console.Write(cleaner3.doCleaner("Toothpaste"));
Cleaner<int> cleanerindex3 = new Cleaner<int>();
Console.Write(cleanerindex3.doCleaner(3));
Console.WriteLine();
}
public void removeCleaner(Cleaner removeCleaner)
{
Console.WriteLine("Enter food name you want to remove");
cleanerRemover = Console.ReadLine();
}
}
}
I can update a List using "single line" updates, but I'd like to update multiple items on a single line, similar to the way the List is initialized.
Here is my code:
public class Players
{
public int id;
public string Rank = "";
public string PlayerName = "";
public string LName = "";
public string FName = "";
public string Team = "";
}
List<Players> newList = new List<Players>();
newList.Add(new Players() { id = 111, PlayerName = "Alpha" });
newList.Add(new Players() { id = 222, PlayerName = "Beta" });
newList.Add(new Players() { id = 333, PlayerName = "Gamma" });
newList[0].FName = "Joe";
newList[0].LName = "Smith";
newList[0].Team = "Yankees";
// newList[1] ={ FName="Babe" , Lname="Ruth", Team="Boston"};
foreach(var item in newList)
{
Console.WriteLine(item.id+" "+item.PlayerName+" "+item.FName+" "+item.LName+" "+item.Team);
}
I want to use something like below to update the list object with multiple items with one line. But this line throws and exception "FName does not exist in current context"
This is the error line // newList[1] ={ FName="Babe" , Lname="Ruth", Team="Boston"};
How do I create/format the correct way to update a List object?
If you want to set those three properties with a one liner, why not implementing a method in the Player class?
public class Player {
//...
public void SetProperties(string Fname, string Lname, string team)
{
FName = fName,
LName = lName,
Team = team
}
}
Then you can do
var newList = new List<Player>();
//...
newList[0].SetProperties("Babe", "Ruth", "Boston");
Edit: #godot suggested that is better to have a method to update just some properties of the Player object. A way to achieve this goal is reflection and anonymous types.
I propose a refactoring of the SetProperties method:
public class Player
{
public int Id { get; set; }
public string Rank { get; set; }
public string PlayerName { get; set; }
public string LName { get; set; }
public string FName { get; set; }
public string Team { get; set; }
public void SetProperties(object obj)
{
foreach (var prop in obj.GetType().GetProperties())
{
var propertyToUpdate = this.GetType().GetProperty(prop.Name);
if(propertyToUpdate != null) propertyToUpdate.SetValue(this, prop.GetValue(obj));
}
}
By implementing this method you can update your list object like this:
newList[0].SetProperties( new { FName = "Babe", LName = "Ruth", Team = "Boston" } );
You can create/format the entire player by creating a new player and overwriting everything.
newList[1] = new Players() { FName="Babe" , Lname="Ruth", Team="Boston"};
I have a requirement to reflect on a object get all properties that are collections and
1)GetCount for each collection
2)GetTotalCount (allCollectionCount)
3)Call a method with this collection.
Below is what I have done so far with a made up noddy structure for semplicity.
I am stuck in how to call this method and how to get count for collection.
Any suggestions?
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main()
{
var request = GetDataRequest();
//Get all properties
List<PropertyInfo> propInfoList =
new List<PropertyInfo>(request.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public));
//Get collections only
var myClassCollections=propInfoList.Where(xxx => xxx.PropertyType.GetInterfaces().Any(x => x == typeof (IEnumerable))).ToList();
var totalCountForAllCollections=????
foreach (var col in myClassCollections)
{
//How do I call my Method DoSomething
// DoSomething<?>(col.?????)
}
}
public void DoSomething<T>(List<T> objectCollection)
{
//etc...
}
private static DataRequest GetDataRequest()
{
DataRequest request = new DataRequest();
request.Addresses.Add(new Address
{
Id = 1,
City = "London",
Postcode = "32131",
Street = "London Road"
});
request.Addresses.Add(new Address
{
Id = 2,
City = "NewYork",
Postcode = "3432",
Street = "NewYork Road"
});
request.Customers.Add(new Customer
{
Id = 1,
Name = "Jo",
Surname = "Bloggs",
});
request.Customers.Add(new Customer
{
Id = 1,
Name = "Jon",
Surname = "Bloggs2",
});
request.Customers.Add(new Customer
{
Id = 1,
Name = "Jonny",
Surname = "Bloggs3",
});
return request;
}
}
public class DataRequest
{
public DataRequest()
{
Customers = new List<Customer>();
Orders = new List<Order>();
Addresses = new List<Address>();
}
public List<Customer> Customers { get; set; }
public List<Order> Orders { get; set; }
public List<Address> Addresses { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
public class Order
{
public int Id { get; set; }
public string Name { get; set; }
public string OrderNo { get; set; }
}
public class Address
{
public int Id { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string Postcode { get; set; }
}
}
quick and dirty, here you go...
// ..
static class Program
{
static void Main()
{
var request = GetDataRequest();
//Get propertyValues for properties that are enumerable (i.e. lists,arrays etc)
var collectionProperties = request.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(propertInfo => propertInfo.PropertyType.GetInterfaces().Any(x => x == typeof(IEnumerable)))
.Select(p => p.GetValue(request, null))
.Cast<IEnumerable<object>>().ToList();
var totalCountForAllCollections = 0;
// iterate through the list of propertyValues
foreach (var collectionPropertyValue in collectionProperties)
{
totalCountForAllCollections += collectionPropertyValue.Count();
collectionPropertyValue.DoSomething();
}
System.Console.WriteLine("The total count for all collections is : {0}", totalCountForAllCollections);
System.Console.WriteLine("press any key to exit");
System.Console.ReadLine();
}
public static void DoSomething<T>(this IEnumerable<T> objectCollection)
{
//etc...
// N.B. you will have to use typeof(T) to implement logic specific to the type
// If the logic in this method is non-specific to the typeof(T) then Implement logic accordingly
System.Console.WriteLine("The type of the collection is: {0}", objectCollection.GetType());
System.Console.WriteLine("The count of items in this collection is:{0}", objectCollection.Count());
}
// ..
}
// ..
I have below scenario:
This is my class structure :
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public System.Collections.ObjectModel.Collection<Likes> Likes { get; set; }
}
public class Likes
{
public string Sport { get; set; }
public string Music { get; set; }
public string Food { get; set; }
public string Place { get; set; }
}
When I serialize object of User class then it will generate the below json string :
{"FirstName":"Naresh",
"LastName":"Parmar",
"Likes": [{"Sport":"Cricket",
"Music":"Classic",
"Food":"Gujarati",
"Place":"India"}]
}
I want to generate above json string like below:
{"FirstName":"Naresh",
"LastName":"Parmar",
"Sport":"Cricket",
"Music":"Classic",
"Food":"Gujarati",
"Place":"India"
}
I want the nested properties as primary one.
Any help would be appreciated.
Thanks in advance..
EDIT:
{"FirstName":"Naresh",
"LastName":"Parmar",
"Sport":"Cricket,Chess,Football",
"Music":"Classic",
"Food":"Gujarati",
"Place":"India"
}
It's really bad practice, since the code i'll post bellow doesn't have great maintainability, however if that's what you looking for, you can use this. Another class that have the format that you'd like, and have a method that adds a list of likes to the format you've required. That the class you should serialize to JSON:
class NestedUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Sport { get; set; }
public string Music { get; set; }
public string Food { get; set; }
public string Place { get; set; }
public void AddLikes(System.Collections.ObjectModel.Collection<Likes> likes)
{
foreach (Likes like in likes)
{
Sport += like.Sport + ",";
Music += like.Music + ",";
Food += like.Food + ",";
Place += like.Place + ",";
}
if (Sport != string.Empty)
{
Sport = Sport.Substring(0, Sport.Length - 1);
}
if (Music != string.Empty)
{
Music = Music.Substring(0, Music.Length - 1);
}
if (Food != string.Empty)
{
Food = Food.Substring(0, Food.Length - 1);
}
if (Place != string.Empty)
{
Place = Place.Substring(0, Place.Length - 1);
}
}
}
Since it's not only limited to Likes objects I'd suggest using dynamic objects. So the User class I propose is as follows:
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public dynamic Details { get; set; }
public User()
{
Details = new ExpandoObject();
}
public void AddSingleDetail(string key, string value)
{
var dict = this.Details as IDictionary<string, Object>;
if (dict.ContainsKey(key))
{
dict[key] += "," + value;
}
else
{
dict[key] = value;
}
}
public void AddDetails(object detailsObject)
{
var type = detailsObject.GetType();
foreach (var prop in type.GetProperties())
{
AddSingleDetail(prop.Name, prop.GetValue(detailsObject).ToString());
}
}
}
You can use it for adding single proerpties or adding an object as a whole. I used reflection to get all the property name and values and add them to the user details.
Sample usage:
static void Main(string[] args)
{
var user1 = new User() { FirstName = "Homer", LastName = "Simpson" };
user1.AddSingleDetail("Sport", "Bowling");
user1.AddSingleDetail("Sport", "Sleeping");
user1.AddSingleDetail("Food", "Donut");
user1.AddSingleDetail("Music", "Rock");
string flattenedHomer1 = ConvertUserToFlattenedJson(user1);
var user2 = new User() { FirstName = "Homer", LastName = "Simpson" };
var likes1 = new Likes() { Food = "Donut", Music = "Rock", Place = "Springfield", Sport = "Bowling" };
var likes2 = new Likes() { Food = "Steaks", Music = "Metal", Place = "Evergreen Terrace", Sport = "Sleeping" };
var proStuff = new ProfessionalStuff() { Title = "Boss" };
user2.AddDetails(likes1);
user2.AddDetails(likes2);
user2.AddDetails(proStuff);
string flattenedHomer2 = ConvertUserToFlattenedJson(user2);
}
And the method performing the JSON conversion is:
public static string ConvertUserToFlattenedJson(User u)
{
dynamic flatUser = new ExpandoObject();
flatUser.FirstName = u.FirstName;
flatUser.LastName = u.LastName;
var dict = u.Details as IDictionary<string, Object>;
foreach (var like in dict)
{
((IDictionary<string, Object>)flatUser)[like.Key] = like.Value;
}
string json = Newtonsoft.Json.JsonConvert.SerializeObject(flatUser);
return json;
}
In my sample above user2 is converted to the following JSON string which I believe is what you are looking for:
{
"FirstName": "Homer",
"LastName": "Simpson",
"Sport": "Bowling,Sleeping",
"Music": "Rock,Metal",
"Food": "Donut,Steaks",
"Place": "Springfield,Evergreen Terrace",
"Title": "Boss"
}
While concatenating strings you can check for null or duplicate values. I didn't handle that part.
For the sake of completeness, here's the ProfessionalStuff class I made up:
public class ProfessionalStuff
{
public string Title { get; set; }
}
Hope this helps.
I have a List that cointains some objects that have 2 string and 2 int properties. I would like to be able to display all the 4 properties of an object based on the content of its first property.
For example: I want to display all the data of all the items of the list that's first property is "Mozart".
Thanks in advance!
I have a really basic class that has 4 properties, 2 strings, and 2 ints, all of them have their respective getters/ setters set to public.
I also have a List that contains some of these objects.
My code looks like this.
Console.WriteLine("Give in the name you want to search for!");
string s = Console.ReadLine();
After this, I would like to check if the first property is "s", and if it is, display all of that given object's data on the screen.
Have a look at this and let me know if you're stuck with any of it :)
void Main()
{
List<Music> myMusic = new List<Music>
{
new Music
{
Artist = "Mozart",
Album = "Mozarts amazing album",
TotalTracks = int.MaxValue,
Etc = int.MinValue
},
new Music
{
Artist = "Foo",
Album = "Bar",
TotalTracks = int.MaxValue,
Etc = int.MinValue
},
};
var mozartsMusic = myMusic.Where(music => music.Artist == "Mozart")
.ToList();
mozartsMusic.ForEach(Console.WriteLine);
}
public class Music
{
public string Artist { get; set; }
public string Album { get; set; }
public int TotalTracks { get; set; }
public int Etc { get; set; }
public override string ToString()
{
return string.Join("\n",this.GetType().GetProperties().Select(p=>string.Format("{0} {1}", p.Name, p.GetValue(this))));
}
}
Something like this would do the trick:
class Datum
{
public string Composer { get; set; }
///wharever other proerties you need
public string DisplayOutput()
{
return this.Composer //+ however you want it displayed
}
}
class Program
{
static void Main(string[] args)
{
List<Datum> data = new List<Datum>();
foreach (var outputLine in data.Where(d => d.Composer == "Mozart").Select(d=>d.DisplayOutput())
{
Console.WriteLine(outputLine);
}
}
}
That should be a possible way to do so:
class Composer
{
public Composer( string lastName, string firstName, int year, int month )
{
LastName = lastName;
FirstName = firstName;
YearOfBirth = year;
MonthOfBirth = month;
}
public string LastName { get; set; }
public string FirstName { get; set; }
public int YearOfBirth { get; set; }
public int MonthOfBirth { get; set; }
public override string ToString()
{
return string.Format( "{0} {1} {2} {3}", LastName, FirstName, YearOfBirth.ToString(), MonthOfBirth.ToString() );
}
}
class Program
{
private static new List<Composer> composerList = new List<Composer>();
static void Main( string[] args )
{
composerList.Add( new Composer( "Mozart", "Wolfgang", 1756, 1 ) );
composerList.Add( new Composer( "Vivaldi", "Antonio", 1678, 3 ) );
Console.WriteLine( "Please enter a name you want to search for!" );
string name = Console.ReadLine();
ShowComposerData( name );
}
private static void ShowComposerData( string name )
{
foreach( Composer comp in composerList )
{
if( comp.LastName == name )
{
Console.WriteLine( comp.ToString() );
}
}
}
}