I'm building a Worker service for Windows who gets data from another program on the system.
at this point i have all data that is need now i want to keep a list with up to date data.
When i run the application for the Zones i get System.Int32[] what i would love to see is the data from System.Int32[]
how to obtain this?
List<BroadcastModel> activeOmroep = new List<BroadcastModel>();
for (int o = 0; o < webcontent.Length; o++)
{
for (int i = 0; i < webcontent[o].Zones.Length; i++)
{
}
activeOmroep.Add(new BroadcastModel
{
Id = webcontent[o].Id,
Name = webcontent[o].Name,
Recording = webcontent[o].Recording,
Zones = webcontent[o].Zones
}) ;
My BroadcastModel class looks like the following:
public class BroadcastModel
{
public int Id { get; set; }
public string Name { get; set; }
public int[] Channels { get; set; }
public bool Recording { get; set; }
public int Type { get; set; }
public int Volume { get; set; }
public int[] Zones { get; set; }
}
Thanks in advance.
for testing purpose i added the following:
foreach (var omroep in activeOmroep)
{
Console.WriteLine("Broadcast ID: " + omroep.Id);
Console.WriteLine("Broadcast Name: " + omroep.Name);
Console.WriteLine("Broadcast is recording: " + omroep.Recording);
Console.WriteLine("Broadcast Zones: " + omroep.Zones);
Console.WriteLine("****************************");
}
but then i got the system.int32[]
Whenever you are printing data using Console.WriteLine(), it calls .ToString() method, if .ToString() is not overridden then it calls Object.ToString() method. Object.ToString() prints type in the string format.
In your case Console.WriteLine("Broadcast Zones: " + omroep.Zones); is printing System.Int32[], because it is calling ToString() method with the basic behavior.
To solve your issue, I would suggest to Override ToString() method in BroadcastModel class and return string which you want to print.
To print array elements, use string.Join() method.
Concatenates the elements of a specified array or the members of a
collection, using the specified separator between each element or
member.
public class BroadcastModel
{
public int Id { get; set; }
public string Name { get; set; }
public int[] Channels { get; set; }
public bool Recording { get; set; }
public int Type { get; set; }
public int Volume { get; set; }
public int[] Zones { get; set; }
public override string ToString()
{
return $"ID : {this.Id}, \nName: {this.Name} \nIs recording: {this.Recording} \nZones : {string.Join(", ", this.Zones)}";
}
}
Now you can print List<BroadcastModel> using foreach loop,
foreach(var broadcastmodel in activeOmroep)
Console.WriteLine(broadcastmodel);
Related
Although the thing I want to do seems be really trivial I can not find a way to achieve what I want. I know there exist multiple questions how to put class properties into the list together and separate it by a comma like that on SO, but none of them seemed to be relevant to my case.
I have a class Form defined as follows:
public class Form
{
public string CustomerName { get; set; }
public string CustomerAdress { get; set; }
public string CustomerNumber { get; set; }
public string OfficeAdress { get; set; }
public string Date { get; set; }
public Boolean FunctionalTest { get; set; }
public string Signature { get; set; }
public Form()
{
}
}
In the MainPage.xaml.cs, I create a List<Form> with the Form class properties and subsequently I would like to create a string with all of those class properties separated by a comma. For that case I use basic Join method with Select which converts any kinds of objects to string.
I do that by createCSV method inside MainPage.xaml.cs :
void createCSV()
{
var records = new List<Form>
{
new Form {CustomerName = customerName.Text,
CustomerAdress = customerAdress.Text,
CustomerNumber = customerNumber.Text,
OfficeAdress = officeAdress.Text,
Date = date.Date.ToString("MM/dd/yyyy"),
FunctionalTest = testPicker.ToString()=="YES" ? true : false,
Signature = signature.Text
}
};
string results = String.Join(",", (object)records.Select(o => o.ToString()));
}
The problem is instead of the desirable outcome which is:"Mark Brown,123 High Level Street,01578454521,43 Falmouth Road,12/15/2020,false,Brown"
I am getting: "System.Linq.Enumerable+SelectListIterator'2[MyApp.Form,System.String]"
PS. As you have noticed I am newbie in C#. Instead of non constructive criticism of the code, please for a valuable reply which would help me to understand what am I doing wrong.
Thanks in advance
In the Form class, You can override the ToString() method and use System.Reflection to get your comma string.
Form.cs
public class Form
{
public string CustomerName { get; set; }
public string CustomerAdress { get; set; }
public string CustomerNumber { get; set; }
public string OfficeAdress { get; set; }
public string Date { get; set; }
public bool FunctionalTest { get; set; }
public string Signature { get; set; }
public override string ToString()
{
string modelString = string.Empty;
PropertyInfo[] properties = typeof(Form).GetProperties();
foreach (PropertyInfo property in properties)
{
var value = property.GetValue(this); // you should add a null check here before doing value.ToString as it will break on null
modelString += value.ToString() + ",";
}
return modelString;
}
}
Code
List<string> CSVDataList = new List<string>();
List<Form> FormList = new List<Form>();
...
foreach (var data in FormList)
{
CSVDataList.Add(data.ToString());
}
Now you have a list of string CSVDataList with each Form object's data in comma style
P.S.
for DateTime
var value = property.GetValue(this);
if(value is DateTime date)
{
modelString += date.ToString("dd.MM.yyyy") + ",";
}
My Main problem is : if i add "N" group to company and check it in the last , i see all of "Man"s arrange into all of groups like together ?
i this my problem is in the definition of class or references .
This is my code :
public class Man
{
public int Code { get; set; }
public string Name { get; set; }
public int Priority { get; set; }
public int Stoptime { get; set; }
public Boolean Lunch { get; set; }
public DateTime Arrival { get; set; }
public DateTime Departure { get; set; }
public int LunchTime { get; set; }
}
public class Group
{
public List<Man> People { get; set; }
public double Speed { get; set; }
public double Rate { get; set; }
public double Surcharge { get; set; }
public double TotalRate { get; set; }
}
public class Company
{
public List<Group> Groups { get; set; }
public Group BestGroup { get; set; }
public double Rate { get; set; }
public double Surcharge { get; set; }
public double FullRate { get; set; }
}
private List<Man> ShufflePosts(List<Man> ShufflePeoples)
{
List<Man> Temp = ShufflePeoples;
List<Man> Commixed = new List<Man>();
Random rand = new Random();
do
{
int shf = rand.Next(0, Temp.Count);
Commixed.Add(Temp[shf]);
Temp.RemoveAt(shf);
} while (Temp.Count > 1);
Commixed.Add(Temp[0]);
return Commixed;
}
public void CAStart(List<Man> Peoples)
{
var _Race = new Company();
_Race.Groups = new List<Group>();
for (int i = 0; i < 5; i++)
{
var Gr = new Group();
Gr.People = ShufflePosts(Peoples);
_Race.Groups.Add(Gr);
}
}
In the code Commixed.Add(Temp[0]); VS show me error index out of range.
I check the variable and see below data:
ShufflePeoples.Count = 0, Temp.Count = 0, Commixed.Count = 1
Why this happens ?
Where is my problem ?
Why you get the error:
Your do while loop runs until Temp.Count > 1 isn't true - which will happen when you removed all items from it with line Temp.RemoveAt(shf);.
Then you try accessing Temp[0] (the first item) but temp is empty and you get an index out of range error.
Try to change your loop's condition and avoid accessing a specific position in the collection without checking that that position exists. Or better still use a simple while instead and then you won't need to specially address the last item in Temp
A nice solution for shuffling:
var suffled = ShufflePeoples.OrderBy(item => Guid.NewGuid());
Change your loop to avoid index out of range error:
while (Temp.Count > 0)
{
int shf = rand.Next(0, Temp.Count);
Commixed.Add(Temp[shf]);
Temp.RemoveAt(shf);
};
When you remove item from Temp, you also remove it from ShufflePeoples because you refer Temp = ShufflePeoples, to avoid it, just make new list then copy items from ShufflePeoples to Temp.
You remove all Temp items in do-while loop, so when you try to access Temp[0] after loop, it will give you index out of range.
For the first time, ShufflePosts method will remove all the contents of the ShufflePeoples.
Therefore the second time you run ShufflePosts method, ShufflePeoples or Temp' is basically empty, which means if you try to accessTemp[0]`, it will give you index out of range Exception.
My 2 cents:
Avoid assigning Temp = ShufflePeoples, instead do Copy Constructor Temp = new List<Man>(ShufflePeoples), to make sure that you do not adjust the parameter accidentally
Always check your initial condition of your parameter argument.
I have a c# object 'Product' with a property called: Offset
In the database the field is of type nvarchar(50)
I will be storing a JSON value in it such as the following: { "y": 0, "m": 0, "d": 0 }
I would like to know a good way of working with a property like this in my code. Here is how I currently am doing it:
public class Product
{
public int Id {get; set;}
public string Description {get; set;}
public decimal Price {get; set;}
public int OffsetYears { get; set; }
public int OffsetMonths { get; set; }
public int OffsetDays { get; set; }
public string Offset
{
get
{
Offset offset = new Offset()
{
Y = OffsetYears,
M = OffsetMonths,
D = OffsetDays
};
return JsonConvert.SerializeObject(offset);
}
set
{
OffsetObj offset = JsonConvert.DeserializeObject<Offset>(value);
OffsetYears = offset.Y;
OffsetMonths = offset.M;
OffsetDays = offset.D;
}
}
private class OffsetObj
{
public int Y { get; set; }
public int M { get; set; }
public int D { get; set; }
}
}
So then when I accept values from the User in the UI I would set the OffsetYears, OffsetMonths, and OffsetDays properties.. So in my repository I can just save Offset.
And when retrieving values from the database I will simply work with OffsetYears, OffsetMonths, and OffsetDays properties in my code.
Is there a better way to handle this sort of thing? I just feel like I am not utilizing all of my c# resources. Like what if another developer accidentally sets Offset through the code assuming any format of string can go in it.
Or am I better off just creating 3 separate integer fields in the database and avoiding all of this...
I would hold the values in a field of your private type. Consider this approach:
public class Product
{
private OffsetObj _offset = new OffsetObj();
public int Id { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public int OffsetYears
{
get { return _offset.Y; }
set { _offset.Y = value; }
}
public int OffsetMonths
{
get { return _offset.M; }
set { _offset.M = value; }
}
public int OffsetDays
{
get { return _offset.D; }
set { _offset.D = value; }
}
public string Offset
{
get
{
return JsonConvert.SerializeObject(_offset);
}
set
{
_offset = JsonConvert.DeserializeObject<OffsetObj>(value);
}
}
private class OffsetObj
{
public int Y { get; set; }
public int M { get; set; }
public int D { get; set; }
}
}
This way, the field offset will hold the values for the offset.
Like what if another developer accidentally sets Offset through the code assuming any format of string can go in it.
JsonConvert will throw a JsonReaderException if trying to set the Offset property to a string that does not match JSON-format. In my opinion this is expected. To clarify further, you could name your property to OffsetJson.
However, I fail to see the benefit in this simple case to store your information as JSON. If you are using a relational database, you may as well just store your values in separate columns.
This question is very similar to this answer, but I need to do it for all objects in a List instead of just one.
Think of workouts, you might write:
Bench Press: 135x10, 185x10, 225x8, 275x5, 315x3
Dumbbell Press: 65x12, 85x12, 95x10, 100x8, 100x8
That is, you have a list of exercises, and each exercise has a list of sets/reps. You want to, for each exercise in the list, convert its list of sets/reps into the form above.
The classes look like:
public class Workout
{
public int WorkoutId { get; set; }
public string Name { get; set; }
public List<Activity> Activities { get; set; }
public DateTime Date { get; set; }
}
// Activity is an instance of an exercise,
// i.e., you bench press, dumbbell press, etc... all in one workout
public class Activity
{
public int ActivityId { get; set; }
public Exercise Exercise { get; set; }
public List<Set> Sets { get; set; }
}
// Sets just hold Weight and Reps
public class Set
{
public int SetId { get; set; }
public int Weight { get; set; }
public int Reps { get; set; }
}
So, for each Set in an Activity, I want set.Weight + "x" + set.Reps, and for each Activity in an Exercise, I want:
"the string we just got for set 1, the string we just got for set 2"
Based on the answer I linked earlier, I've come up with this:
string.Join(",",
workout.Activities.Select(
activity => activity.Sets.Select(
set => set.Weight.ToString() + "x" + set.Reps.ToString()
)
));
But that yields:
System.Linq.Enumerable+WhereSelectListIterator2[MyLifts.Models.Set,System.String],System.Linq.Enumerable+WhereSelectListIterator2[MyLifts.Models.Set,System.String],System.Linq.Enumerable+WhereSelectListIterator2[MyLifts.Models.Set,System.String],System.Linq.Enumerable+WhereSelectListIterator2[MyLifts.Models.Set,System.String],System.Linq.Enumerable+WhereSelectListIterator`2[MyLifts.Models.Set,System.String]
You have nested selects, the inner select returns an IEnumerable<String> which you can join, but the outer select returns an IEnumerable<IEnumerable<String>>.
Are Exercise and Workout the same thing? Assuming they are try:
string.Join(",",
workout.Activities.Select(
activity => activity.Exercise.Name + ": " + String.Join(",",
activity.Sets.Select(
set => set.Weight.ToString() + "x" + set.Reps.ToString()
)
)
));
I have a question regarding the way I'm storing data in my application, keep in mind I'm not too experienced with C#. So, I am grabbing data from a file and able to print it all out using a foreach loops
try
{
var doc = new HtmlDocument();
doc.LoadHtml(htmlDoc);
var i = 0;
foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//tr"))
{
if (i <= 6) { Console.Write("[Type1]"); }
if (i >= 7 && i <= 12) { Console.Write("[Type2 i + " : "); }
if (i >= 13 && i <= 23) { Console.Write("[Type3] i + " : "); }
if (i >= 24 && i <= 33) { Console.Write("[Type4]" + i + " : "); }
if (i >= 34 && i <= 39) { Console.Write("[Type5]" + i + " : "); }
if (i > 38 || i < 1) { Console.Write("Error LTZ or GTV"); }
Console.Write(row.Elements("td").First().InnerText);
Console.Write(" - ");
Console.WriteLine(row.Elements("td").Last().InnerText);
i++;
}
}
This part works fine, it prints them all out with the appropriate tag in front of the data. What I am trying to accomplish is instead of printing the data out I want to store it in my class. I have it modeled like this currently
public class House
{
//Downstairs
public int DBedrooms {get; set; }
public int DKitchens {get; set; }
public int DLiving { get; set; }
//upstairs
public int UBedrooms { get; set; }
public int UKitchens { get; set; }
public int ULiving { get; set; }
//Neighborhood
public string NSchool { get; set; }
public int NSchoolDist { get; set; }
public int NCrime { get; set; }
...
...
...
}
there's about 40 public ints in the class currently and I'm just wondering what a better way to store the data would be!
Every structure that can have duplicates should have their own class instead of just declaring a lot of properties, and I personally like storing such structures in a list. you would also want to add them to the list in the right order so you don't mistake the upstairs for the downstairs.
For the ability to have many floors in a house i would organize like so:
public class Floor {
public int DBedrooms {get; set; }
public int DKitchens {get; set; }
public int DLiving { get; set; }
}
public class House {
public List<Floor> Floors{get;set;}
public string NSchool { get; set; }
public int NSchoolDist { get; set; }
public int NCrime { get; set; }
}
FYI: if you might be able to use a Repeater instead of programmably creating html (http://www.w3schools.com/aspnet/aspnet_repeater.asp), although I don't know if it fits your use case.
Edit: also if you are the one creating the source files then consider deserialization from xml.
First of all, what is the use case of the object? If it's simply a data transfer object then leaving it as it is should be fine. However if parts of the object are to be used throughout the application then you could break it down into pieces like so:
public class Downstairs : Floor
{
public IList<Room> Rooms { get; set;}
}
public class Upstairs : Floor
{
public IList<Room> Rooms { get;set; }
}
public class House
{
public HouseOwner Owner { get;set; }
public readonly IList<Floor> Floors { get; private set;}
public House(HouseOwner owner, IList<Floor> floors)
{
this.Owner = owner;
this.Floors = floors;
}
public void AddFloor(Floor floor)
{
this.Floors.Add(floor);
}
public int TotalFloors()
{
return this.Floors.Count();
}
}
By modelling your data like this each object encapsulates its own and properties data making it a little more organised than a large generalised class.