Adding objects to an array in the constructor - c#

I am making a simple c# web service that takes in a name and returns the corresponding phone number.
So I created a contact class with a name field and a number field
Here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PhoneService
{
class Contact
{
String name;
int number;
//constructor to make new contact
public Contact(String name, int number)
{
this.name = name;
this.number = number;
}
}
}
And here is my web service class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PhoneService
{
class PhoneBook : IPhoneBook
{
Contact[] contactList = new Contact[4];
//constructor
public PhoneBook ()
{
contactList[0] = new Contact("Mary Jones", 1800252525);
contactList[1] = new Contact("Bob Smith", 1800343434);
contactList[2] = new Contact("Martin Dunne", 1800797979);
contactList[3] = new Contact("Sarah Mitchel", 1800898989);
}
//method to look up name
public string lookUpNumberByName(string name)
{
//variable to hold name entered
String nameEntered = name; ;
/**
code to compare the name entered with the
the names of the contact objects.
If the name is a match with a contact name then return
the associated number
**/
//return number corresponding to the name
return null;
}
}
}
So I am trying to make 4 simple contact objects stored in an array then when I enter a name I can check if it matches one of them and return the relevant phone number.
The problem is with the constructor
My assignment says-
"Have the service maintain a list of names and phone numbers in a collection in memory which is initialised in the constructor for the service class."
So I don't know what parts I should have in the constructor and what should be outside in the main class.Hopefully someone can let me know the best way I can go ahead with this.
Thanks in advance
UPDATE
I have redone my code and made it a bit more simple by removing the contact class.
Here it is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PhoneService
{
class PhoneBook : IPhoneBook
{
static String[] nameList = new String[4];
static String[] numberList = new String[4];
//constructor
public PhoneBook()
{
nameList[0] = ("Mary Jones");
nameList[1] = ("Bob Smith");
nameList[2] = ("Martin Dunne");
nameList[3] = ("Martin Dunne");
numberList[0] = ("1800252525");
numberList[1] = ("1800343434");
numberList[2] = ("1800797979");
numberList[3] = ("1800898989");
}
//method to look up name
public String lookUpNumberByName(String name)
{
try
{
if (string.Equals(name, nameList[0], StringComparison.CurrentCultureIgnoreCase))
{
return numberList[0];
}
if (string.Equals(name, nameList[1], StringComparison.CurrentCultureIgnoreCase))
{
return numberList[1];
}
if (string.Equals(name, nameList[2], StringComparison.CurrentCultureIgnoreCase))
{
return numberList[2];
}
if (string.Equals(name, nameList[3], StringComparison.CurrentCultureIgnoreCase))
{
return numberList[3];
}
}
catch (System.Exception)
{
return ("That name is not found");
}
}//end of lookUpNumberByName method
}//end of class phonebook
}// end of phoneservice
My lookUpNumberByName method is getting an error saying not all code paths return a value

You're basically asking about encapsulation. Generally, you want to think of what parts of the class you want to expose kind of like an engineer thinks about what controls of a car to expose to a driver. Basically, if no one on the outside will need to use this property of this method, don't expose it, just leave it be.
What your assignment is effectively asking you to do is not to expose a property but to set a contact list via a service constructor. So if you need to set your contact list, shouldn't you just pass a contact list into the constructor for your phone book? And remember that you can have multiple constructors and if you don't specify one that takes no arguments, you won't be able to simply declare an instance of that class without passing arguments.

You mean something like this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PhoneService
{
class PhoneBook : IPhoneBook
{
private static List<Contact> _contactList = new List<Contact>();
//constructor
public PhoneBook (List<Contact> contactList)
{
_contactList = contactList;
}
public PhoneBooks()
{
}
}
}
you can use it like this
using System;
class Program
{
static void Main()
{
var contactList = new List<Contact>();
contactList.Add(new Contact("Mary Jones", 1800252525));
contactList.Add(new Contact("Bob Smith", 1800343434));
contactList.Add(new Contact("Martin Dunne", 1800797979));
contactList.Add(new Contact("Sarah Mitchel", 1800898989));
var phoneBook = new PhoneBook(contactList);
}
}

Related

does not contain a public instance definition for 'getenumerator' for each error thrown

I am trying to loop through a list that contains student data using foreach method however I get the error QA does not contain a public instance definition for 'getenumerator' for each.
My QA class is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Test
{
class QA
{
private List<Student> students;
public QA()
{
students = new List<Student>();
string line;
using (StreamReader reader = new StreamReader("/Users/jvb/Desktop/Students.txt"))
{
line = reader.ReadLine();
var s = line.Split(',');
int id = int.Parse(s[0]);
int houseNo = int.Parse(s[3]);
var status = int.Parse(s[7]);
Student sData = new Student(id, s[1], s[2], houseNo, s[4], s[5], s[6], (StudentStatus)status);
AddStudent(sData);
}
}
public List<Student> GetStudents()
{
return students;
}
public void AddStudent(Student student)
{
students.Add(student);
}
}
}
This simply loops through a text file with various bits of data and adds each student to a students list. Inside my program.cs file I created an instance of the QA class and tried to loop through it like so:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
class Program
{
static void Main(string[] args)
{
QA students = new QA();
foreach (var s in students)
{
Console.WriteLine(s.GetStudents());
}
}
}
}
I am quite new to c#, could anyone care to explain what I am misunderstanding/doing wrong?
You are direct use object that is not enuerable, you have to access it member which is implemented IList and that is enumerable.
you are doing it all wrong.
You are iterating class object which is not iterable. you don't need foreach.
static void Main(string[] args)
{
QA students = new QA();
var studentList= s.GetStudents(); //you get all the students not you can iterate on this lidt
foreach(var student in studentList)
{
//here you can access student property like
Console.WriteLine(student.Name); //I assume Name is a property of Student class
}
}

Importing CSV File in C# Convert the string list to specific classtype list

First i have to mention that iam not that good in programming but i try my best.
Following situation: I imported several csv files into string lists. Now i want to cast those lists as the classdatatype i need. For example class Student, in the studentlistmanager class iam improting the list and trying to convert it to List but it seems like it wont be that easy, i tried to create an object of that list and add the object to the student list but that wont work either. Instead of the values i get System.String[] values into my list.
internal void ImportStudentList(CsvImportService csv)
{
List<string> newList = new List<string>();
csv = new CsvImportService("Klassenlisten_20160906.csv");
for(int i = 0; i <= csv.ClassList.Count;i++)
{
for(int x = 0; x <= csv.ClassList.Count;x++)
{
string line = csv.ClassList[i];
// Student st = new Student(line);
// ListOfStudents.Add(st);
newList.Add(line);
ListOfStudents = newList.Cast<Student>().ToList();
}
}
}
I would really appreciate any help. Thanks in advance!
Is that what you are looking for ? Saving the Data of the csv File in the Student
List.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Stackoverflow_Konsole_Test
{
class Program
{
static void Main(string[] args)
{
string CSV_FILE_PATH = #"filepath.csv";
List<string> FULL_CSV_STRING = new List<string>();
Students Student1 = new Students();
FULL_CSV_STRING.Add(File.ReadAllText(CSV_FILE_PATH));
foreach (string line in FULL_CSV_STRING)
{
Student1.add(line);
}
foreach (string line in Student1.getlist())
{
Console.WriteLine(line);
}
Console.ReadLine();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Stackoverflow_Konsole_Test
{
class Students
{
private List<string> List_of_students = new List<string>();
public Students()
{
//constructor
}
public void add(string line)
{
this.List_of_students.Add(line);
}
public List<string> getlist()
{
return this.List_of_students;
}
}
}

How do I get the index of string variable value into ObservableCollection?

In my windows phone application I am using observablecollection like below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.UserData;
using System.Windows.Media;
using Microsoft.Phone.Maps.Controls;
using System.Collections.ObjectModel;
using System.Collections;
namespace GetContacts
{
public partial class createGroups : PhoneApplicationPage
{
string buttonName = "";
public static ObservableCollection<Group> groupbtn;
public createGroups()
{
InitializeComponent();
groupbtn = new ObservableCollection<Group>();
}
private void btn_Click(object sender, RoutedEventArgs e)
{
string buttonText = "abc"
string index = groupbtn.IndexOf(buttonText);
}
}
}
And below is the Group class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using GetContacts.Resources;
using Microsoft.Phone.UserData;
namespace GetContacts
{
public class Group
{
public string Name { get; set; }
/*public string content { get; set; }
private string[] numberofbtns = new string[5];
public string[] NumberOfBtns
{
get { return numberofbtns; }
set { numberofbtns = value; }
}*/
//object[] array1 = new object[5];
public Group()
{
}
public Group(Button btn)
{
Name = btn.Name;
}
}
}
But its getting me two errors below:
Error 1: at this line groupbtn.IndexOf(buttonText):
The best overloaded method match for 'System.Collections.ObjectModel.Collection<GetContacts.Group>.IndexOf(GetContacts.Group)' has some invalid arguments
Error 2 at this line groupbtn.IndexOf(buttonText) on it buttonText:
Argument 1: cannot convert from 'string' to 'GetContacts.Group'
How do I resolve it or kindly suggest me how do I get the index of string variable value into observablecollection.
Waiting for your reply.
Thanks.
You cannot use IndexOf with a string on an ObservableCollection<Group>. You need a Group. You also have to override Equals in class Group (also override GetHashCode):
public class Group
{
public string Name { get; set; }
public override bool Equals(object obj)
{
Group g2 = obj as Group;
return g2 != null && g2.Name == this.Name;
}
public override int GetHashCode()
{
return Name == null 0 : Name.GetHashCode();
}
}
Now you're able to use IndexOf:
Group searchGroup = new Group { Name = buttonText };
int index = groupbtn.IndexOf(searchGroup);
or use a different approach, for example using LINQ:
int index = groupbtn
.Select((g, i) => new { Group = g, Index = i })
.Where(x => x.Group.Name == buttonText)
.Select(x => x.Index)
.DefaultIfEmpty(-1)
.First();
Those are the same error. The problem is that you have a collection of type Group and then you are trying to find a matching Group with a string. You have to pass a Group to .IndexOf to find the index of the Group you are trying to find.
This type of error is something you need to be able to figure out yourself from the compiler error.
The best overloaded method match for 'System.Collections.ObjectModel.Collection<GetContacts.Group>.IndexOf(GetContacts.Group)' has some invalid arguments
This clearly means it doesn't like the argument you are passing to this function. It shows the function definition, so you can tell it wants to be passed a Group.
Argument 1: cannot convert from 'string' to 'GetContacts.Group'
You are passing a string to a function that we know accepts a Group. Since it only accepts a Group, it tries to implicitly convert the string to a Group, but there isn't a way for it automatically do that.
The IndexOf method is expecting a Group object, but you're providing a string. ObservableCollections implement IEnumerable, so you may be able to use a Linq expression. Such as...
Group btnGroup = (from g in groupbtn where g.Name == "name" select g).First();
int indexOfGroupButton = groupbtn.IndexOf(btnGroup);
Or something like that. Basically, you first need to find the actual "Group" object, and then you can find the index of that object.

C# Foreach Loop Issue

I was just making this program to experiment with lists and such, and I was curious as to why in the foreach loop the Object always shows up as the "Minecraft" Wish object. Is it because it was the last Wish object to be created? And how can I fix it, so all 3 Wish objects which have been declared show up?
Thanks!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Wish iPod = new Wish("iPod", "Various", 299.00);
Wish Phone = new Wish("New Phone", "Various", 00.00);
Wish Minecraft = new Wish("Minecraft Account", "www.minecraft.net", 30.00);
List<Wish> Wishlist = new List<Wish>();
Wishlist.Add(Phone);
Wishlist.Add(iPod);
Wishlist.Add(Minecraft);
Console.WriteLine("Toby's Wishlist");
Console.WriteLine("If cost is 00.00, the Wish's cost varies.");
Console.WriteLine(" ");
foreach (Wish wish in Wishlist)
{
Console.WriteLine("---Wish---");
Console.WriteLine("Name: {0}", wish.getName());
Console.WriteLine("Store: {0}", wish.getStore());
Console.WriteLine("Cost: ${0}", wish.getCost().ToString());
Console.WriteLine("----------");
Console.WriteLine(" ");
}
Console.ReadLine();
}
}
public class Wish
{
static string Name, Store;
static double ApproxCost;
public Wish(string name, string store, double approxCost)
{
Name = name;
Store = store;
ApproxCost = approxCost;
}
public string getName()
{
return Name;
}
public string getStore()
{
return Store;
}
public double getCost()
{
return ApproxCost;
}
}
}
Remove static from Wish members declaration
static means that the data will be shared across all the instances. So static members are also so called class variables. While not static members - are object variables.
It's because in class Wish you declared Name, Score, and ApproxCost as static.

How to use BinaryReader and correctly input data into file?

I am working on my homework assignment and I am completely stuck! What I am trying to do is to use already defined input and save it to the file by using saveDataTo() method and read the input by using readDataFrom() method.
I am stuck on the first part. I am not sure if I have to initialize the data in Program.cs file first?
I don't know and I am stuck. Here is code and hope for some tips how I can accomplish this.
-- EDIT --
I can add instructions for purpose of both saveDataTo() and readDataFrom() methods:
The saveDataTo( ) method takes a parameter of BinaryWriter. The method
writes the values of all 5 properties of an book object to a file
stream associated with the writer (the association is done in the
Main( ) method of Program class). There is no need to open and close
the file stream and binary writer inside this method.
The readDataFrom( ) method takes a parameter of BinaryReader. The
method reads the values of all five properties of the Book object from
a file stream associated with the reader (the association is done in
the Main( ) method of Program class). There is no need to open and
close the file stream and binary reader inside this method.
So that gives me a clue that I should use and assign the properties to be saved in the file there?
-- EDIT --
Updated the code there. I do have a problem with content that is being saved into the file. I am not being showed the price. Why is that?
ff.APublisherNameTitle FirstNameLastName
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Lab_7
{
class Program
{
private const string FILE_NAME = "lab07.dat";
static void Main(string[] args)
{
//char ask;
/*
do
{
Console.Write("Enter Book Title: ");
publication.Title = Console.ReadLine();
Console.Write("Enter Author's First Name: ");
book.AuthorFirstName = Console.ReadLine();
Console.Write("Enter Author's Last Name: ");
book.AuthorLastName = Console.ReadLine();
Console.Write("Enter Publisher's Name: ");
publication.PublisherName = Console.ReadLine();
Console.Write("Enter Book Price: $");
publication.Price = float.Parse(Console.ReadLine());
Console.Write("Would like to enter another book? [Y or N] ");
ask = char.Parse(Console.ReadLine().ToUpper());
}
while (ask == char.Parse("Y"));
*/
Book book = new Book();
book.Price = 10.9F;
book.Title = "Title";
book.PublisherName = "PublisherName";
book.AuthorFirstName = "FirstName";
book.AuthorLastName = "LastName";
FileStream fileStream = new FileStream(FILE_NAME, FileMode.OpenOrCreate);
BinaryWriter write = new BinaryWriter(fileStream);
book.saveDataTo(write);
write.Close();
fileStream = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read);
BinaryReader read = new BinaryReader(fileStream);
book.readDataFrom(read);
read.Close();
}
}
}
Publication.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Lab_7
{
class Publication
{
private float price;
private string publisherName, title;
public float Price
{
get
{
return price;
}
set
{
price = value;
}
}
public string PublisherName
{
get
{
return publisherName;
}
set
{
publisherName = value;
}
}
public string Title
{
get
{
return title;
}
set
{
title = value;
}
}
public void display()
{
Console.WriteLine("{0}\n{1}\n{2}", title, publisherName, price);
}
}
}
Book.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Lab_7
{
class Book : Publication
{
private string authorFirstName, authorLastName;
public string AuthorFirstName
{
get
{
return authorFirstName;
}
set
{
authorFirstName = value;
}
}
public string AuthorLastName
{
get
{
return authorLastName;
}
set
{
authorLastName = value;
}
}
public new void display()
{
}
public string getAuthorName()
{
return authorFirstName + " " + authorLastName;
}
public void readDataFrom(BinaryReader r)
{
Price = r.ReadInt32();
PublisherName = r.ReadString();
Title = r.ReadString();
authorFirstName = r.ReadString();
authorLastName = r.ReadString();
}
public void saveDataTo(BinaryWriter w)
{
w.Write(base.Price);
w.Write(base.PublisherName);
w.Write(base.Title);
w.Write(AuthorFirstName);
w.Write(AuthorLastName);
}
}
}
Regards.
HelpNeeder.
You're asking whether to define the values in Program.cs or Book.cs, right? Well, it is fine to define the values in Program.cs, you just need to make sure all the values are given before writing the data.
So, since the function takes a BinaryWriter parameter that is supposedly initialized beforehand, this should work:
public void saveDataTo(BinaryWriter w)
{
w.Write(getAuthorName());
//etc...
}
But, just remember that you do need to define all the info somewhere (anywhere) before calling save data.
You assign your parameters to 2 different objects, see:
Publication publication = new Publication();
Book book = new Book();
Both are individual instances residing in memory.
You either have to refer the publication to the book like:
Book book = new Book();
Publication publication = (Publication)book;
or just assign the values currently assigned to the publication directly to the book so:
publication.PublisherName = "PublisherName";
becomes
book.PublisherName = "PublisherName";
Apart from that, you're working in C#, not Java. By convention its normal to start your methods with a Capital (Pascal Case)
EDIT
Your now shown the price when reaidng since you write it as a floating field (or double, cant see the definition) and read it as an integer.
Change from r.ReadInt32(); to r.ReadDouble(); or r.ReadSingle()

Categories