So I'm working on a library management system and I'm new to C# so you may see me here a lot, the issue I'm currently having revolves around this. I'm trying to make it search in my list for the author and it succeeds in doing that, I just don't know how to make it print out the result to make it appear on the console as it currently just prints "Author exists!".
public static void LetaEfterBok()
{
Console.Write("Enter an author to search for a book: ");
string search = Console.ReadLine();
foreach (Bok b in newBok)
{
Bok Bok = new Bok();
if (b.namn.Equals(search))
Console.Write("Author " + Bok.Författare + " exists!");
}
}
If needed, here is the lists and variables
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Bibliotek
{
//Definerar klassen Bok
class Bok
{
public string ID
{ get; set; }
public int tempID;
public string Författare
{ get; set; }
public string namn
{ get; set; }
public int BokCount;
public int x;
}
class Program
{
static List<Bok> newBok = new List<Bok>();
static List<BorrowDetails> borrowList = new List<BorrowDetails>();
static Bok Bok = new Bok();
static BorrowDetails borrow = new BorrowDetails();
//Menyn och startsidan till programmet
static void Main(string[] args)
{
StreamReader readFile = new StreamReader("bokfil.txt");
string s;
while((s = readFile.ReadLine()) != null)
{
Bok Bok = new Bok();
string[] BokData = s.Split(',');
Bok.namn = BokData[0];
Bok.Författare = BokData[1];
Bok.ID = BokData[2];
Bok.tempID = int.Parse(Bok.ID);
newBok.Add(Bok);
}
readFile.Close();
try if this method works for you...
public void LetaEfterBok()
{
Console.Write("Enter an author to search for a book: ");
string search = Console.ReadLine();
var book = newBok.FirstOrDefault(b => { return b.namn.Equals(search, StringComparison.OrdinalIgnoreCase); } );
if(book != null)
{
Console.WriteLine("Author " + book.Författare + " exists!");
}
}
I suggest you do the OOP thing and give your class Bok some functionality to display information about itself. You should override the ToString() method such that anytime you do WriteLine(b) where b is a Bok it would print a string with information of the book.
For example:
//Definerar klassen Bok
class Bok
{
public string ID
{ get; set; }
public int tempID;
public string Författare
{ get; set; }
public string namn
{ get; set; }
public int BokCount;
public int x;
public override string ToString()
{
return $"Title:{Författare}, Author:{namn}, ID:{ID} ({BokCount} Count)";
}
}
which can be used in the search as
public static void LetaEfterBok()
{
Console.Write("Enter an author to search for a book: ");
string search = Console.ReadLine();
foreach (Bok b in newBok)
{
if (b.namn.Equals(search))
{
Console.Write($"{b} Exists!");
}
}
}
To add more flexibility, also add a function in the Bok class that tries to match the author, and use the List<T>.Find() method to search the list
//Definerar klassen Bok
public class Bok
{
public string ID { get; set; }
public int tempID;
public string Författare { get; set; }
public string namn { get; set; }
public int BokCount;
public int x;
public override string ToString()
{
return $"Author:{Författare}, Name:{namn}, ID:{ID} ({BokCount} Count)";
}
public bool MatchAuthor(string name) => namn.ToUpper().StartsWith(name.ToUpper());
}
public static void LetaEfterBok()
{
Console.Write("Enter an author to search for a book: ");
string search = Console.ReadLine();
Bok match = newBok.Find((b) => b.MatchAuthor(search));
if (match!=null)
{
Console.Write($"{b} Exists!");
}
}
Related
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ex1
{
internal class Program
{
static void Main(string[] args)
{
createCity("ex", 1, "ex1");
Console.ReadKey();
}
public void createCity(string name, int showOrder, string objectName)
{
City myObj = new City(name, showOrder);
}
}
}
using System;
public class City
{
public City()
{
string name;
static int code = 1;
int showOrder;
City(string name, int showOrder)
{
this.name = name;
this.showOrder = showOrder;
this.code++;
}
}
}
Any idea why? new to C#.
It doesn't know why the class City is, I don't understand why. I created it in the same project with the add option.
I'm just trying to create a new object of the class in the main.
create a constructor like this:
public City()
{
}
or with parameters:
public City(string name, int showOrder)
{
...
}
define the properties or fields of your class outside of the constructor
public class City
{
private string name { get; set; }
private int code { get; set; } = 1;
private int showOrder { get; set; }
}
Your 'code' property / field should not be static. This is causing an error in your constructor
int code = 1;
the reason you can't do createCity() inside the main method is because it is marked as static. Removing the static keyword should work.
private void Main(string[] args)
{
createCity("ex", 1, "ex1");
Console.ReadKey();
}
However you need a static void Main(string[] args) method in a console app, so I made createCity static as well
Full working example:
namespace ex1
{
public class Program
{
private static void Main(string[] args)
{
createCity("ex", 1, "ex1");
Console.ReadKey();
}
public static void createCity(string name, int showOrder, string objectName)
{
City myObj = new City(name, showOrder);
}
}
}
public class City
{
public City()
{
}
private string name { get; set; }
private int code { get; set; } = 1;
private int showOrder { get; set; }
public City(string name, int showOrder)
{
this.name = name;
this.showOrder = showOrder;
this.code++;
}
}
There are many things to fix:
static: Please make sure you understand this concept
This applies to:
static void createCity
code++;
The City class has multiple constructors and the class variable was defined in the wrong place.
You have to set the constructor public or at least internal:
public City(string name, int showOrder)
Corrected code:
Program.cs:
using System;
namespace ex1
{
internal class Program
{
static void Main(string[] args)
{
createCity("ex", 1, "ex1");
Console.ReadKey();
}
public static void createCity(string name, int showOrder, string objectName)
{
City myObj = new City(name, showOrder);
}
}
}
City.cs:
namespace ex1
{
public class City
{
string name;
static int code = 1;
int showOrder;
public City()
{
}
public City(string name, int showOrder)
{
this.name = name;
this.showOrder = showOrder;
code++;
}
}
}
Please try this following code :
using System;
namespace ex1
{
internal class Program
{
static void Main(string[] args)
{
City c = createCity("ex", 1, "ex1");
Console.WriteLine(c.ToString());
Console.ReadLine();
}
public static City createCity(string name, int showOrder, string objectName)
{
return new City(name, showOrder);
}
}
public class City
{
private string name;
private int code = 1;
private int showOrder;
public City(string name, int showOrder)
{
this.name = name;
this.showOrder = showOrder;
this.code++;
}
public override string ToString() => $"name: {name}; code:{code}; showOrder: {showOrder}";
}
}
I have list in class
public List<Igrac> Igraci { get; set; } = new List<Igrac>();
The class:
class Igrac
{
public string Ime { get; set; }
public string Prezime { get; set; }
public string Pozicija { get; set; }
public int Godine { get; set; }
public Igrac(string Ime, string Prezime, string Pozicija, int Godine)
{
this.Ime = Ime;
this.Prezime = Prezime;
this.Pozicija = Pozicija;
this.Godine = Godine;
}
}
Added new list elements:
noviklb.DodavanjeIgraca(new Igrac("Petar", "Petrovic", "Krilo", 1992));
noviklb.DodavanjeIgraca(new Igrac("Badr", "Hari", "Napad", 1993));
The method for adding is working OK. The problem is that when I use Console.WriteLine I get an error like this:
System.Collections.Generic.List`1[zadatak.Program+Igrac]
I Googled and foreach is solution but I cant do it right. Do I need to write foreach as method?
class Igrac
{
public string Ime { get; }
public string Prezime { get; }
public string Pozicija { get; }
public int Godine { get; }
public Igrac(string Ime, string Prezime, string Pozicija, int Godine)
{
this.Ime = Ime;
this.Prezime = Prezime;
this.Pozicija = Pozicija;
this.Godine = Godine;
}
}
public override string ToString()
{
return $"{Ime} {Prezime} {Pozicija} {Godine}";
}
Now you can use.
string myStringDate = new Igrac("Petar", "Petrovic", "Krilo", 1992).ToString();
ALSO NOTE: It would be good to make you properties get only.
Working link:
https://dotnetfiddle.net/zMNiln
use this code:
public void showList(List<Igrac> noviklb)
{
foreach (var item in noviklb)
{
Console.WriteLine("Ime : " + item.Ime);
Console.WriteLine("Prezime : " + item.Prezime);
Console.WriteLine("Pozicija : " + item.Pozicija);
Console.WriteLine("Godine : " + item.Godine);
Console.WriteLine("Get New Record****************** ");
}
}
I'd like to parse a csv file in my course that I attend, The cvs file looks like this:
john; 3.5; 32111
etc
I've created a Class for that:
class Student
{
public string name { get; set; }
public double average { get; set; }
public int social_number { get; set; }
public Student(string name, double average, int social_number)
{
this.name = name;
this.average = average;
this.social_number = social_number;
}
public void CSV_digest(string csv_line)
{
if (csv_line != "")
{
string[] chunks = csv_line.Split(';');
name = chunks[0];
average = Convert.ToDouble(chunks[1]);
social_number = Convert.ToInt32(chunks[2]);
}
}
}
I don't really know how to propagate the Student type array:
class Program
{
static void Main(string[] args)
{
StreamReader csv = new StreamReader("students.csv", Encoding.UTF8);
string[] csv_lines = csv.ReadToEnd().Split('\n');
Student[] students = new Student[csv_lines.Length - 1];
for (int i = 0; i < csv_lines.Length; i++)
{
students[i] =
}
Console.ReadKey();
}
}
Could you please help me with this? I'd really like to utilize classes.
There is really no reason to use a library when the code to read CSV is very simple. See my code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string filename = #"c:\temp\test.csv";
static void Main(string[] args)
{
StreamReader csv = new StreamReader(filename);
string line = "";
List<Student> students = new List<Student>();
while((line = csv.ReadLine()) != null)
{
students.Add(new Student(line));
}
Console.ReadKey();
}
}
class Student
{
public string name { get; set; }
public double average { get; set; }
public int social_number { get; set; }
public Student(string csv_line)
{
if (csv_line != "")
{
string[] chunks = csv_line.Split(';');
name = chunks[0];
average = Convert.ToDouble(chunks[1]);
social_number = Convert.ToInt32(chunks[2]);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment5
{
public class Person
{
public string Name { get; set; }
public DateTime BirthDate { get; set; }
}
public class Student : Person
{
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public static int countS = 0;
public static List<string> studentlist = new List<string>();
public Student()
{
studentlist.Add(Name);
countS++;
}
public static int GetActiveInstances()
{
return countS;
}
}
class MainProgram
{
static void Main(string[] args)
{
// Instantiate three Student objects.
Student Student1 = new Student();
Student Student2 = new Student();
Student Student3 = new Student();
Student1.Name = "John";
Student2.Name = "Joe";
Student3.Name = "Jacob";
for (int i = 0; i < Student.studentlist.Count; i++) // Loop with for.
{
Console.WriteLine(Student.studentlist[i]);
}
Console.WriteLine("Press any key to continue . . . ");
Console.ReadKey();
}
}
}
Hi guys. What I have in mind is that I want to automatically store every student being initiated in an array/list that I created and eventually, I want to output these students in the console.
Can anyone enlighten me what I did wrong on my program?
Supposedly it will output the 3 names I declare. What I have on the output for the posted program are all blank.
**Next Related Question **
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment6
{
public class Person
{
public string Name { get; set; }
public string Address { get; set; }
public virtual void GetInfo()
{
Console.WriteLine("Name: {0}", Name);
Console.WriteLine("Address: {0}", Address);
}
}
public class Student : Person
{
public void SetStudentInfo(string name, string address)
{
Name = name;
Address = address;
}
}
public class Course //class represents university course
{
private ArrayList studentList = new ArrayList();
public ArrayList StudentList
{
get { return studentList; }
set { studentList = value; }
}
//how can I implement this such that I can have the StudentList be updated and printed
// out to the console from the main
public void ListStudents()
{
foreach (Student i in StudentList)
{
Console.WriteLine(i.ToString());
}
}
}
class MainProgram
{
static void Main(string[] args)
{
var Student1 = new Student { Name = "John" };
var Student2 = new Student { Name = "Joe" };
var Student3 = new Student { Name = "Jacob" };
Course course1 = new Course();
course1.StudentList.Add(Student1);
course1.StudentList.Add(Student2);
course1.StudentList.Add(Student3);
course1.ListStudents();
Console.WriteLine();
Console.WriteLine("Press any key to continue . . . ");
Console.ReadKey();
}
}
}
I have this code and I want to output every student in my arraylist, the foreach loop should be on the course class. Still, the code is connected on my question so I just ask it here. Can anyone help me revise it? thanks
What I do not get is these line:
public static int countS = 0;
public static List<string> studentlist = new List<string>();
public Student()
{
studentlist.Add(Address);
countS++;
}
What I would suggest is to move these out so that the class is something like this:
public class Person
{
public string Name { get; set; }
public DateTime BirthDate { get; set; }
}
public class Student : Person
{
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
And that main is something like this:
static void Main(string[] args)
{
// Instantiate three Student objects.
Student Student1 = new Student();
Student Student2 = new Student();
Student Student3 = new Student();
Student1.Name = "John";
Student2.Name = "Joe";
Student3.Name = "Jacob";
var studentlist = new List<Student>{Student1,Student2,Student3};
foreach (var student in studentlist)
{
Console.WriteLine(student.Name);
}
Console.WriteLine("Press any key to continue . . . ");
Console.ReadKey();
}
Instead of adding a property that hasn't been set yet (which is what you're currently doing in the default constructor - you're adding the Name property before it's been set), you can add a reference to the class instance using the this keyword, so the properties of the items in your list (like Name or Address) get updated when they are set on the class instance.
Also, you don't need a separate variable to keep track of the number of students, since you can just use the Count property of the list.
Here's a way you can do this:
public class Student : Person
{
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public static List<Student> AllStudents = new List<Student>();
public Student()
{
AllStudents.Add(this);
}
public static int GetActiveInstances()
{
return AllStudents.Count;
}
}
Usage:
public static void Main()
{
var student1 = new Student {Name = "John"};
var student2 = new Student {Name = "Joe"};
var student3 = new Student {Name = "Jacob"};
foreach (var student in Student.AllStudents)
{
Console.WriteLine(student.Name);
}
}
Output:
JohnJoeJacob
UPDATE
One way you can protect your internal list, yet still let others query it, would be to make the list private, and then expose a public property that returns a copy of the list, which prevents people from affecting your private instance if they call .Add() or .Remove() on it, or try to set it to a new List<Student>.
Here's an example:
public class Student : Person
{
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
// This is the "official" list. It's private so cannot be changed externally
private static readonly List<Student> StudentList = new List<Student>();
// This property returns a COPY of our private list
public static List<Student> AllStudents
{
get
{
var copyOfList = new List<Student>();
copyOfList.AddRange(StudentList);
return copyOfList;
}
}
public Student()
{
// Add the student to our private list
StudentList.Add(this);
}
public static int StudentCount()
{
// Return the count from our private list
return StudentList.Count;
}
}
I have this:
public class Blah
{
public int id { get; set; }
public string blahh { get; set; }
}
public class Doh
{
public int id { get; set; }
public string dohh { get; set; }
public string mahh { get; set; }
}
public List<???prpClass???> Whatever(string prpClass)
where string prpClass can be "Blah" or "Doh".
I would like the List type to be class Blah or Doh based on what the string prpClass holds.
How can I achieve this?
EDIT:
public List<prpClass??> Whatever(string prpClass)
{
using (var ctx = new ApplicationDbContext())
{
if (prpClass == "Blah")
{
string queryBlah = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Blah>(queryBlah).ToList();
return result;
}
if (prpClass == "Doh")
{
string queryDoh = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Doh>(queryDoh).ToList();
return result;
}
return null
}
}
you have to have a common supertype:
public interface IHaveAnId
{
int id { get;set; }
}
public class Blah : IHaveAnId
{
public int id { get; set; }
public string blahh { get; set; }
}
public class Doh : IHaveAnId
{
public int id {get;set;}
public string dohh { get; set; }
public string mahh { get; set; }
}
then you can do:
public List<IHaveAnId> TheList = new List<IHaveAnId>();
and in some method:
TheList.Add(new Blah{id=1,blahh = "someValue"});
TheList.Add(new Doh{id =2, dohh = "someValue", mahh = "someotherValue"});
to iterate through the list:
foreach(IHaveAnId item in TheList)
{
Console.WriteLine("TheList contains an item with id {0}", item.id);
//item.id is allowed since you access the property of the class over the interface
}
or to iterate through all Blahs:
foreach(Blah item in TheList.OfType<Blah>())
{
Console.WriteLine("TheList contains a Blah with id {0} and blahh ='{1}'", item.id, item.blahh);
}
Edit:
the 2 methods and a int field holding the autovalue:
private int autoValue = 0;
public void AddBlah(string blahh)
{
TheList.Add(new Blah{id = autovalue++, blahh = blahh});
}
public void AddDoh(string dohh, string mahh)
{
TheList.Add(new Doh{id = autovalue++, dohh = dohh, mahh = mahh});
}
Another Edit
public List<object> Whatever(string prpClass)
{
using (var ctx = new ApplicationDbContext())
{
if (prpClass == "Blah")
{
string queryBlah = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Blah>(queryBlah).ToList();
return result.Cast<object>().ToList();
}
if (prpClass == "Doh")
{
string queryDoh = #"SELECT ... ";
var result = ctx.Database.SqlQuery<Doh>(queryDoh).ToList();
return result.Cast<object>.ToList();
}
return null;
}
}
in the view you then have to decide what type it is. In asp.net MVC you can use a display template and use reflection to get a good design. But then i still don't know what technology you are using.
Yet another Edit
TestClass:
public class SomeClass
{
public string Property { get; set; }
}
Repository:
public static class Repository
{
public static List<object> Whatever(string prpClass)
{
switch (prpClass)
{
case "SomeClass":
return new List<SomeClass>()
{
new SomeClass{Property = "somestring"},
new SomeClass{Property = "someOtherString"}
}.Cast<object>().ToList();
default:
return null;
}
}
}
And a controller action in mvc:
public JsonResult Test(string className)
{
return Json(Repository.Whatever("SomeClass"),JsonRequestBehavior.AllowGet);
}
then i called it with: http://localhost:56619/Home/Test?className=SomeClass
And got the result:
[{"Property":"somestring"},{"Property":"someOtherString"}]
Is this what you are trying to do?
public class Blah
{
public int id { get; set; }
public string blahh { get; set; }
}
public class Doh
{
public int id { get; set; }
public string dohh { get; set; }
public string mahh { get; set; }
}
class Program
{
public static List<T> Whatever<T>(int count) where T: new()
{
return Enumerable.Range(0, count).Select((i) => new T()).ToList();
}
static void Main(string[] args)
{
var list=Whatever<Doh>(100);
// list containts 100 of "Doh"
}
}