Making an ID system for objects in C# - c#

Im trying to make a program about books, and it needs and ID system. I want to get the access to the information about a specifict object with the book ID. For example:
Console.Write("What ID is the book ")
//tempId = **ID**
int tempId = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(book**ID**.title); //.title = the title of the book
How can I do something like that?
I thought about doing that with a static class atribute, but I'm pretty sure this isn't possible.

What I would do would be to create a class "book" containing the attributes you need (id, name, publication date...) and store all these books in an array of type map with the id as primary key. I do not know if I solve your question with this, if your question was not this one, ask me again the question and I will try to help you.
This would be an example of the class "book":
#include <string>
class Book {
public:
Book(int id, std::string name, std::string publicationDate)
: id_(id), name_(name), publicationDate_(publicationDate) {}
int id() const { return id_; }
std::string name() const { return name_; }
std::string publicationDate() const { return publicationDate_; }
private:
int id_;
std::string name_;
std::string publicationDate_;
};
And so you can create the map I was telling you about:
int main() {
std::map<int, Book> library;
library[123] = Book(123, "El Quijote", "1605-01-01");
library[456] = Book(456, "Cien aƱos de soledad", "1967-05-01");
library[789] = Book(789, "Don Juan Tenorio", "1844-01-01");
int bookId = 456;
auto it = library.find(bookId);
return 0;
}
The above code creates a map with three books and retrieves in it the one with id 456.

Related

c# record - using with keyword to modify properties

I recently ran into the record keyword in c#, I'm able to create a an instance of a record and modify it both by assigning a value regularly and both by using the keyword with.
Is there any difference between the two ways, when should one use with?
public record Car{
public Car(string name, int age){
Name = name;
Age = age;
}
public string Name;
public int Age;
}
public static void Main()
{
var car = new Car("Reno", 15);
car.Name = "Honda";
Console.WriteLine(car.Name);
car = car with {Name = "BMW"};
Console.WriteLine(car.Name);
}
One of the main reasons for records introduction in C# - make it easier to create immutable data models. with functionality was created to provide easy to use syntax to create a copy of immutable instance with changed properties. So car = car with {Name = "BMW"}; actually does not modify original reference type but creates a new one and assigns it to the variable.
The difference can easily be seen with next code:
var car = new Car("Reno", 15);
var car2 = car;
car.Name = "Honda";
Console.WriteLine(car.Name);
Console.WriteLine(car2.Name);
car = car with {Name = "BMW"};
Console.WriteLine(car.Name);
Console.WriteLine(car2.Name);
Also couple of notes:
it is recommended to use autoproperties instead of fields, i.e.:
public record Car{
public Car(string name, int age){
Name = name;
Age = age;
}
public string Name { get; set; };
public int Age { get; set; };
}
in case you need immutable data records provide neat syntax which automatically generates constructor and init-only properties:
public record Car(string Name, int Age);
They are not the same. The difference is that with creates a copy of the record. According to the proposal:
A with expression allows for "non-destructive mutation", designed to produce a copy of the receiver expression with modifications in assignments in the member_initializer_list.
[...]
First, receiver's "clone" method (specified above) is invoked and its result is converted to the receiver's type. Then, each member_initializer is processed the same way as an assignment to a field or property access of the result of the conversion.
So there is an extra step of copying the record if you use with.
See also the decompiled C# code on SharpLab. Notice the <Clone> call before setting car2.Name = "BMW", which does not happen when setting car.Name = "Honda".
Car car = new Car("Reno", 15);
car.Name = "Honda";
Console.WriteLine(car.Name);
Car car2 = car.<Clone>$();
car2.Name = "BMW";
Console.WriteLine(car2.Name);

C# Match User Inputs to Array

I'm writing some code where I have some information about customers stored in an array called members (id, initials). I then ask the user for their id and initials and match the inputs to the stored information from array members. If they match I move on. However I get an error in my coding: "an object reference is required to access non-static field method or property". The error comes from the if statements. Any suggestions on how to correct this issue?
Some background info: I have two classes, one called Customer and one called Menu. The Menu is the main class while Customer is the class I reference from.
This is from my Menu class:
int L = 0;
string I = "";
Customer[] members = new Customer[2];
members[0] = new Customer(3242, "JS");
members[1] = new Customer(7654, "BJ");
Console.Write("\nWhat is your Loyalty ID #: ");
L =Convert.ToInt32(Console.ReadLine());
Console.Write("\nWhat is your first and last name initials: ");
I = Console.ReadLine();
if (L==Customer.GetId())
{
if (I == Customer.GetInitials())
{
Console.WriteLine("It matches");
}
}
else
{
Console.WriteLine("NO match");
}
Console.ReadKey();
}
}
}
This from my Customer class
private int id;
private string initials;
public Customer ()
{
}
public Customer(int id, string initials)
{
SetId(id);
SetInitials(initials);
}
public int GetId()
{
return id;
}
public void SetId(int newId)
{
id = newId;
}
public string GetInitials()
{
return initials;
}
public void SetInitials(string newInitials)
{
initials = newInitials;
}
The error means exactly what it says. You can't access the GetId() function of Customer by calling Customer.GetId() because GetId() only works on an instance of Customer, not directly through the Customer class.
Customer.GetId(); //this doesn't work
Customer myCustomer=new Customer(); myCustomer.GetId(); //this works
To check the user's input against your array of inputs, you need to iterate through the array (or alternatively, use Linq).
I'm going to use a generic list, because there's not really a good reason to use arrays in most cases.
List<Customer> customers=new List<Customer>();
Customers.Add();//call this to add to the customers list.
foreach(var c in customers)
{
if(c.GetId() == inputId)
{
//match!
}
else
{
//not a match
}
}
You can also improve your Customer class by using properties, or auto properties (which doesn't need a backing field). Here's an auto property example:
public string Id {get; set;} // notice there's no backing field?
Using the above auto property syntax would allow you do to this:
var customer = new Customer();
string id = customer.Id; // notice there's no parentheses?
Properties and auto properties allow for a cleaner syntax than having to write Java-style separate getters/setters.

C# classes - basic example [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
This is basically my first attempt to understand the classes in C#. I've went through several tutorials on the internet, but the thing I'm missing the most and what I haven't found anywhere yet, is a simple good example.
I have some idea how my basic program should look like and I would appreciate your help:
using System;
namespace Introduction_to_classes
{
class Person
{
int Age;
string Name;
int DateOfBirth()
{
return 2013 - Age;
}
}
class Program
{
public static void Main()
{
Person Mother = new Person(35, Alice);
Person Son = new Person(12, Johny);
Mother.Name = "Lucy"; // Just changing the value afterwards
if(Mother.Age > Son.Age)
{
int year = Mother.DateOfBirth();
Console.WriteLine("Mom was born in {0}.", year);
}
Console.ReadLine();
}
}
}
It's just an idea, it definitely doesn't work. But more than anything else it would help me if you can correct it to the working example...
class Person
{
public int Age { get; set; }
public string Name { get; set; }
public Person(int age, string name)
{
Age = age;
Name = name;
}
public int DateOfBirth()
{
return 2013 - Age;
}
}
class Program
{
public static void Main()
{
Person Mother = new Person(35, "Alice");
Person Son = new Person(12, "Johny");
Mother.Name = "Lucy"; // Just changing the value afterwards
if (Mother.Age > Son.Age)
{
int year = Mother.DateOfBirth();
Console.WriteLine("Mom was born in {0}.", year);
}
}
}
Some useful links: properties, constructor
using System;
namespace Introduction_to_classes {
class Person {
public int Age;
public string Name;
public int DateOfBirth() {
return 2013-Age;
}
}
class Program {
public static void Main() {
Person Mother=new Person {
Age=35,
Name="Alice"
};
Person Son=new Person {
Age=12,
Name="Johny"
};
Mother.Name="Lucy"; // Just changing the value afterwards
if(Mother.Age>Son.Age) {
int year=Mother.DateOfBirth();
Console.WriteLine("Mom was born in {0}.", year);
}
Console.ReadLine();
}
}
}
The problem is that you're referring to a constructor that doesn't exist:
Person Mother = new Person(35, Alice);
The first argument here is an int, the second should be a string as far as I understand. But a string literal should be marked with double quotes, so that line should be:
Person Mother = new Person(35, "Alice");
Same for the following line.
Now you probably want a constructor that takes types of these arguments and you want to save these values to the new object, I assume. So, add this in your Person class:
public Person(int a, string n)
{
this.Age = a;
this.Name = n;
}
And, finally, you should make your Age and Name fields accessible to the other class, by marking them internal or public:
public int Age;
public string Name;
After that, you should be good to go.
First of all: new Person(35, "Alice") implies that class Person defines a constructor public Person(int age, string name). Alternatively, you'll have to call new Person() { Age = 35, Name = "Alice" } which only works as long as you have not defined a constructor, or have defined a constructor that takes 0 arguments, such as public Person() (notice how I put "Alice" within quotation marks? That's because you didn't define a string called Alice, so Alice is an unknown object)
Next we have Mother.Name = "Lucy", which won't work, because Name is not discoverable. The class Person does define a Name, but since you didn't specify an access modifier, such as public or private, class Program doesn't even know it exists and thus cannot access it. So you have to use public string Name instead of string Name. It is also considered to be good style to always specify your access modifier. The same applies to public int Age and public int DateOfBirth() as well.
To know more about access modifiers refer to http://msdn.microsoft.com/en-us/library/ms173121.aspx

Returning data from one method to another within a class

Thanks for help with the question I just submitted about anonymous classes. Now I understand more. Here's a bit more of an example:
public class abc {
public xx doAction() {
return ( new { ID = 5, Name= "Dave" } );
}
public void doStart() {
var a = doAction();
var b = a.ID;
var c = a.Name;
}
}
So am I correct in saying that the most ideal way to do this would be to declare a class XYX and use it like this:
public class abc {
public XYZ doAction() {
return ( new XYZ { ID = 5, Name= "Dave" } );
}
public void doStart() {
var a = doAction();
var b = a.ID;
var c = a.Name;
}
}
The class would be only used for this one data transfer between the two methods.
I think you meant: return new XYZ(5, "Dave")
Anyways, your solution is okay but there is no reason to create a new class simply to share data. You can use a hashtable/array/dictionary or whatever class suits you best to share data. If you want to do something special with the XYZ class, or it has methods you wish to call from it, then you would have to create a new class XYZ and return it. Though, if you just want to share data, use a data structure that's already available to your use.
That would work yes. If it is the most ideal or not is hard to say. Since you are using the variables "ID" and "Name" it kinda indicates that you are working with domain objects from a database, and if so, you will probably need the class for a lot more than just this one method.
What about the class ABC? What kind of class is that? Because you could also do this:
public class abc{
private int _id;
private string _name;
public void DoAction(){
_id = 5;
_name = "Dave";
}
public void DoStart(){
var b = _id;
var c = _name;
}
}
But remember to use proper naming for your classes, so you have an idea of what they are used for.
Yes, though if your class has trivial properties you can consider using existing .Net classes:
1) You can consider using System.Tuple (.Net 4.0) but you will not have good property names anymore:
var result = Tuple.Create(5, "Dave");
int id = result.Item1;
string name = result.Item2;
2) You can use KeyValuePair if it is applicable:
var result = new KeyValuePair<int, string>(5, "Dave");
int id = result.Key;
string name= result.Value;

Polymorphism - exercise

Alright, so this is the exercise:
Define a class named student,
containing three grades of students.
The class will have a function that
calculates the grades average. Now,
define a class named student1 which
will be derived from student and will
add a function to calculate the sum of
the grades.In the Main program, define
a student variable and object of type
student1. Perform placement of the
object to variable and run the
function of student1.
Note: This is not homework, I'm learning this my own.
This is the code:
class Student
{
protected int grade1, grade2, grade3;
public Student(int grade1, int grade2, int grade3)
{
this.grade1 = grade1;
this.grade2 = grade2;
this.grade3 = grade3;
}
public double Average()
{
return (grade1 + grade2 + grade3) / 3;
}
}
class Student1 : Student
{
public Student1(int grade1, int grade2, int grade3)
: base(grade1, grade2, grade3)
{
}
public double Sum()
{
return grade1 + grade2 + grade3;
}
}
class Program
{
static void Main(string[] args)
{
}
}
I don't really know what to do in the main class, how do I perform this placement and also, I wanted to know what's the benefit of doing it, let me know if I have mistakes so far, thanks alot.
OK: I guess this is what they're looking for, although the english is a little ropey:
1) Declare student variable
Student s;
2) Declare Student1 object
Student1 s1 = new Student1(1,2,3);
3) Perform placement of object to variable:
s = s1;
4) Run the function (Note you'll have to cast s to Student1 type to access the Type specific function Sum)
Console.WriteLine(((Student1)s).Sum());
Maybe this is what it means.. although its really badly worded in my eyes.
In the Main program, define a student variable and object of type student1. Perform placement of the object to variable and run the function of student1.
static void Main(string[] args)
{
//define a student variable and object of type student1.
Student student = new Student1(100, 99, 98);
//Perform placement of the object to variable and run the function of student1
var sum = ((Student1)student ).Sum();
}
The primary flaw I see in your code from an OOP perspective is making Student1 extend from Student. When using inheritance, make sure it's a true extension (is a). You would be better served by making 1 student class and implementing the Sum and Average methods.
I think the following would be sufficient from an OOP perspective.
class Student
{
protected int grade1, grade2, grade3;
public Student(int grade1, int grade2, int grade3)
{
this.grade1 = grade1;
this.grade2 = grade2;
this.grade3 = grade3;
}
public double Average()
{
return (grade1 + grade2 + grade3) / 3;
}
public double Sum()
{
return grade1 + grade2 + grade3;
}
}
Following exactly what was described by the exercise:
// Define a student variable.
Student s;
// And object of type Student1.
Student1 s1 = new Student1(10, 5, 8);
// Perform placement of the object to variable.
s = s1;
// And run the function of Student1.
// But it makes no sense...
s1.Sum();
// Maybe the exercise wants it:
((Student1)s).Sum();
// Which makes no sense too, since is making an idiot cast.
// But for learning purposes, ok.
Well, I don't believe this exercise is taking any advantage of polymorphism in C#. I suggest you reading the link to see a real usage sample.

Categories