Will these code be safe in memory in c#? - c#

I have a question about the following code.
First, these codes worked well.
However, there is no declaration only defined about “courses” in class Student.If in the Constructor of Student the argument is constant, will these code be safe?
Thanks for helping!:)
public class Student
{
public string name;
public int age;
public string[] courses;
public Student(string _name, int _age,params string[] _courses)
{
name = _name;
age = _age;
courses = _courses;//is this OK if _courses is constant?
}
}
public class work : MonoBehaviour
{
void Start()
{
/*
string[] courses={"math", "English"};
Student Tom = new Student("Tom",18,courses);
//It's wrong!
*/
Student Tom = new Student("Tom", 18, "math", "English");
string Tom_text = JsonUtility.ToJson(Tom);
Debug.Log(Tom_text);
}
}

The way you have it, anyone can change the Student object at anytime.
If you do not want anyone changing anything about the Student object once it has been created, then make it immutable like this:
public class Student
{
public string Name { get; private set; }
public int Age { get; private set; }
public IEnumerable<string> Courses { get; private set; }
public Student(string name, int age, params string[] courses)
{
this.Name = name;
this.Age = age;
this.Courses = courses;
}
}
Now people cannot change the the properties because the setters are private.
And to follow the .NET naming convention, do not use - underscores in parameter names and use Pascal Notation for property names. I have removed the underscores and used Pascal Notation for property names.
EDIT
#diemaus mentioned a good point in the comments to this answer, in C# 6:
You can actually remove the private set entirely, and just leave it { get; }. This is allowed as long as long as you only set the properties in the constructor.

Related

Relationship of classes

I have two classes, i want to put instances of a class Bear in a list from class Cave like below, but that code doesn't works. Should classes be in relationship? How can I change code?
class Bear
{
public Bear(int age, string name)
{
this.Age = age;
this.Name = name;
}
}
class Cave
{
List<Bear> cave = new List<Bear>();
cave.Add(new Bear(16, "Johnny"));
cave.Add(new Bear(10,"Herman"));
}
If you are getting any errors, please post them. You can't put code like that directly in the class. All executable code must be inside a method. Move the code in your Cave class into a method:
class Bear
{
public int Age { get; set; }
public string Name { get; set; }
public Bear(int age, string name)
{
this.Age = age;
this.Name = name;
}
}
class Cave
{
List<Bear> cave = new List<Bear>();
public Cave()
{
cave.Add(new Bear(16, "Johnny"));
cave.Add(new Bear(10,"Herman"));
}
}

Instantiating an object inside another object? (c#)

Firstly I'd like to say that I truly sorry if this is an idiotic question but I just started learning about Classes and I've thought that I managed to understand it but this confused the heck outta me so seems like I didn't
I'm doing this C# OOP edx course where I had to make 5 classes (student, teacher, UProgram, degree, course) in different class files and there's this task:
Instantiate a UProgram object called Information Technology.
Instantiate a Degree object, such as Bachelor, insude the UProgram object.
Instantiate a Course object called softeng inside the Degree object.
Was done, (hopefully) no issues with that one
and 3. - eh.
How I was thinking (bear in mind, im a beginner so):
First I've thought of nested classes but I wasn't really sure about how they work and didn't think I could put the classes in different files as they should be nested (?)
And then I tried something with the constructor but I couldn't see how I could make it work
So now my final try was to create methods inside the classes (except for the Teacher and Student one as they won't have anything ""belonging to them"" like a Course has students and teachers belonging to it
So I have the method in the form of (- let's say we're in the Degree class, having a method for creating several Courses for this degree -):
public void Newcourse(string Cname, Course sth)
{
sth = new Course();
sth = Cname;
}
And before I can use it, I have to write the
Course softeng = new Course();
line aka make an instance of the Course class before I can do the 3. point of the task
The whole code:
UProgram.cs
public class UProgram
{
public void Newdegree(string Dname, Degree sth)
{
sth = new Degree();
sth.Dname = Dname;
}
}
Degree.cs
public class Degree : UProgram
{
public string Dname { get; set; }
public void Newcourse(string Cname, Course sth)
{
sth = new Course();
sth.Cname = Cname;
}
}
Course.cs
public class Course : Degree
{
public void NewTeacher(string FirstName, string LastName, Teacher sth)
{
sth = new Teacher();
sth.FirstName = FirstName;
sth.LastName = LastName;
}
public void NewStudent(string FirstName, string LastName, Student sth)
{
sth = new Student();
sth.FirstName = FirstName;
sth.LastName = LastName;
}
public string Cname { get; set; }
}
Teacher.cs
public class Teacher : Course
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Student.cs
public class Student : Course
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Program.cs
class Program
{
static void Main(string[] args)
{
var Information_Technology = new UProgram();
Degree bachelors = new Degree();
Information_Technology.Newdegree("Bachelors", bachelors);
Course softeng = new Course();
bachelors.Newcourse("Software Engineering", softeng);
Teacher t1 = new Teacher();
softeng.NewTeacher("Colin", "Firth", t1);
Student s1 = new Student();
softeng.NewStudent("Mary", "Sue", s1);
Student s2 = new Student();
softeng.NewStudent("Joseph", "Jojo", s2);
Console.ReadLine();
}
}
I know-I know, it's very convoluted and I'm not even sure whether this is good or not but that was all I could come up with and I'd be very grateful if any of you could help me out (in a tone that won't make me cry)
Thank you and again, sorry for this mess of a code, eh, i tried
The wording does seem a bit strange, but I believe they are simply saying that this class should contain a property of the type it is meant to "contain", and instantiate it in the constructor. For example:
public class Degree
{
public Course Course { get; set; }
public Degree()
{
Course = new Course();
}
}
public class Course
{
public Student Student { get; set; }
public Course()
{
Student = new Student();
}
}
public class Student
{
public Student()
{
}
}
Upon creating a an instance of Degree, it will create an instance of a Course inside it, which will create an instance of a Student inside it. Thus Degree contains a Course which contains a Student.
The example above is using the constructors to instantiate these but as they are public properties they could also just be created from outside it (in which case the constructors above are unnecessary):
var degree = new Degree();
degree.Course = new Course();
degree.Course.Student = new Student();
Just a few comments:
I have big doubts that you need any inheritance here. For example: Student : Course - I doubt that "Student is a Course" :) . So, you probably need some composition here. I don't know (and can't remember) what diamonds in your picture exactly means, but can guess that filled diamond - is one item (or at least one, not sure) and empty means many items.
So, here how I would do this (you can split each class to separate file):
public class UProgram
{
public string Name { get; set; }
public Degree Degree { get; set; }
public UProgram(string name, Degree degree)
{
Name = name;
Degree = degree;
}
}
public class Degree
{
public string Name { get; set; }
public Course Course { get; set; }
public Degree(string name, Course course)
{
Name = name;
Course = course;
}
}
public class Course
{
public List<Teacher> Teachers { get; set; }
public List<Student> Students { get; set; }
public string Name { get; set; }
public Course(string name, List<Teacher> teachers, List<Student> students)
{
Name = name;
Teachers = teachers;
Students = students;
}
}
public class Teacher
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
and Main function:
static void Main(string[] args)
{
var teachers = new List<Teacher>
{
new Teacher
{
FirstName = "Colin",
LastName = "Firth"
}
};
var students = new List<Student>
{
new Student
{
FirstName = "Mary",
LastName = "Sue"
},
new Student
{
FirstName = "Joseph",
LastName = "Jojo"
}
};
var softEngCourse = new Course("Software Engineering", teachers, students);
var bachelorDegree = new Degree("Bachelor", softEngCourse);
var technologyProgram = new UProgram("Technology", bachelorDegree);
Console.ReadLine();
}
I still not sure that this exactly what your course is expected from you, this is how I would write code like this (with some minor changes, but it doesn't matter here).
Why in that way? Because it is almost always better to build an object in a "working" state when it explicitly receives everything that it needs, rather than create a raw object that will start in "invalid" state. Secondly, it is usually better to not "bake in" parameters values inside, but give a class consumer (I mean "developer" here) to configure it.
You are misunderstanding the task. Course should not inherit from Degree, since Course is not a Degree. Instead, you will need to define Course data member in your Degree class. Neither Student, nor Teacher is a Course, therefore you should not inherit them from Course. They are members.
I assume that a Degree can be achieved by a single Course.
I assume that a Course has a single Teacher.
I assume that a Course can have multiple Students.
This means that you have a Person class, like this, since both Student and Teacher is a Person:
public class Person {
protected String firstName;
protected String lastName;
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
Now, inherit Teacher from Person:
public class Teacher : Person {
public Teacher(String firstName, String lastName) : base(firstName, lastName) {
}
}
and Student:
public class Student : Person {
public Student(String firstName, String lastName) : base(firstName, lastName) {
}
}
Now, let's define Course:
public class Course {
protected Teacher teacher;
protected List<Student> students;
protected String name;
public String getName() {
return this.name;
}
public Teacher getTeacher() {
return this.teacher;
}
public List<Student> getStudents() {
return this.students;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public void setTeacher(String firstName, String lastName) {
this.teacher = new Teacher(firstName, lastName);
}
public void addStudent(Student student) {
this.students.Add(student);
}
public void addStudent(String firstName, String lastName) {
this.students.Add(new Student(firstName, lastName));
}
public Course(String name) {
this.name = name;
this.students = new List<Student>();
}
}
Now, let's define Degree:
public class Degree {
protected String name;
protected Course course;
public String getName() {
return this.name;
}
public Course getCourse() {
return this.course;
}
public void setCourse(Course course) {
this.course = course;
}
public void setCourse(String name) {
this.course = new Course(name);
}
public Degree(String name) {
this.name = name;
}
}
Now, this is how you achieve what you wanted:
Degree degree = new Degree("mydegree");
degree.setCourse("myCourse");
Course course = degree.getCourse();
course.setTeacher("John", "Smith");
course.addStudent("James", "Doe");

'ConsoleApplication1.Student' does not contain a constructor that takes 1 arguments [duplicate]

This question already has answers here:
C# “does not contain a constructor that takes '1' arguments”
(5 answers)
Closed 6 years ago.
I am Student who is learning c#, when I executed the program got error.
On console: I am expecting to see the string 'Harry'.
Error: 'ConsoleApplication1.Student' does not contain a constructor that takes 1 arguments
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Student student = new Student("Harry");
System.Console.WriteLine(student.ToString());
System.Console.ReadLine();
}
}
class Student
{
public string Name { get; set; }
}
}
Question: How can I solve the program? Anyone guide me, please.
Your class need a constructor with one argument.
Student student = new Student("Harry");
System.Console.WriteLine(student.ToString());
Class:
class Student
{
public string Name { get; set; }
public Student(string Name) //constructor here
{
this.Name = Name;
}
public override string ToString() //overload of ToString
{
return this.Name;
}
}
As Tim mentionend - another way is to leave the class untouched and just set and read the property
Student student = new Student() { Name = "Harry" };
Console.WriteLine(student.Name);
Class:
class Student
{
public string Name { get; set; }
}
You need to change your student class to have a constructor that takes one parameter
class Student
{
public string Name { get; set; }
public Student(string name)
{
this.Name = name;
}
public Student() { }
}
Then create a constructor that takes 1 arguments.
On console, i am expecting to see the string 'Harry'
So, you need to add override to merthod ToString() like:
class Student
{
public string Name {get; set;}
public Student(string name)
{
Name = name;
}
public override string ToString();
{
return Name;
}
}
You did not defined any Constructor, especiall none with 1 argument, but you are trying to use such a by calling Student("Harry") :-).
Define Constructor with String argument and it will be fine.

Using Array of Arrays for One to Many Relationship in C#

I am making a console test with C#.
Actually I have never used of C# but VB.Net. I want to create arrays for one-to-many relationship.
My one is 'A Student' has 'Name','Sex',...,'Courses Taken'.
A Student would take many course, each course has a Title and Included Subject. Each subject has Name, Description and Point.
Like this.
Student
- Name - Sex - Courses Taken
Take Courses
- Course Title - Subject Included
Subject
- Subject Name [Math] [MVC]
- Subject description [Advance] [Building Website]
- Subject Point [6.9] [5.6]
I want to store each entity in Arrays but I don't know how to connect subjects/courses to each Students. And how can I get Student who attending Math or MVC. Because every students can have more then more course/ more than one subjects.
You'll want to create classes to describe your different objects.
class Student
{
string Name { get; set; }
Gender Sex { get; set; } // write an enum for this
IEnumerable<Course> CoursesTaken { get; set; }
}
class Course
{
string Title { get; set; }
Subject Subject { get; set; }
}
class Subject
{
string Name { get; set; }
string Description { get; set; }
double Points { get; set; }
}
Using List to create enumerations of instances of these new types allow you to use LINQ to select or evaluate members of the list (nested for loops work as well):
// populate a list of students called studentList
//...
// use LINQ to select the students you want
var mathResults = studentList.Where(student => student.CoursesTaken.Any(course => course.Subject.Name == "Math"));
I feel like I've done with it in good way...
Pls check my code for my ques! ^^
I first made 3 classes as below..
class Students
{
public string StudentName;
public int StudSize;
public bool StudSex;
public List<Take_Courses> tcourses;
public Students() { }
public Students(string name, int size, bool sex, List<Take_Courses> tcourses)
{
StudentName = name;
StudSize = size;
StudSex = sex;
this.tcourses = tcourses;
}
}
and
class Take_Courses
{
public string classname;
public List<Arr_Courses> arr_Course;
public Take_Courses() { }
public Take_Courses(string classname, List<Arr_Courses> arr_courses)
{
this.classname = classname;
arr_Course = arr_courses;
}
}
class Arr_Courses
{
public string cosname;
public string cosdesc;
public float cospoint;
public Arr_Courses() { }
public Arr_Courses(string name, string description, float point)
{
cosname = name;
cosdesc = description;
cospoint = point;
}
}
I then initialized values in Main class as below;
Arr_Courses acos=new Arr_Courses();
Arr_Courses acos1=new Arr_Courses("Math","Advance Math1",9.5f);
Take_Courses cos=new Take_Courses();
Take_Courses cos_take1=new Take_Courses("Info Tech",new List<Arr_Courses>{acos1});
Students stu=new Students();
Students Stu1 = new Students("Milla", 22, true,new List<Take_Courses>{cos_take1});
I then make another List to be generated names of student and use for looping and assign each one to List.
I think some important part is this.
if (arr_stud[i].tcourses[j].arr_Course[k].cosname.Equals("Math"))
{
Math_Stud++;
MathStudents[i] = arr_stud[i];
}
I am sharing this if anyone needs something like this. Any ungraded codes is appreciated to be shared. Thanks so so.

Calling one constructor by other

what are the advantages of calling one constructor by other if there are multiple constructors?
Thanks
You don't repeat yourself.
A change in implementing one constructor also affects all the other constructors, instantly.
Copy and Pasting code is bad and should be avoided.
the same advantages you get when you do method overloading : you don't repeat the same code
public class Person
{
public Person(string name,string lastName )
{
Name = name;
LastName = lastName;
}
public Person(string name, string lastName,string address):this(name,lastName)
{
//you don't need to set again Name and Last Name
//as you can call the other constructor that does the job
Address = Address;
}
public string Name { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}
Looking at the already posted answers i will just they that you always walk the way from the default constructor down to the most specialized constructor. Trying to do the same the other way around always leads to code duplications or problems:
The good way:
public class Foo()
{
public Foo()
: this(String.Empty)
{ }
public Foo(string lastName)
: this(lastName, String.Empty)
{ }
public Foo(string lastName, string firstName)
: this(lastName, firstName, 0)
{ }
public Foo(string lastName, string firstName, int age)
{
LastName = lastName;
FirstName = firstName;
Age = age;
_SomeInternalState = new InternalState();
}
}
The bad way:
public class Foo()
{
public Foo(string lastName, string firstName, int age)
: this(lastName, firstName)
{
Age = age;
}
public Foo(string lastName, string firstName)
: this(lastName)
{
FirstName = firstName;
}
public Foo(string lastName)
: this()
{
LastName = lastName;
}
public Foo()
{
_SomeInternalState = new InternalState();
}
}
The problem of the second example is that the part what to do with all the parameters is now cluttered over all constructors, instead implemented in just one (the most specialized). Just imagine you like to derive from this class. In the second example you have to override all constructors. In the first example you only have to override the most specialized constructor to get full control over every constructor.
If you want to pass default values to a base constructor.
public class YourClass
{
private int SomeInt;
public YourClass() : this(0)
{
// other possible logic
}
public YourClass(int SomeNumber)
{
SomeInt = SomeNumber;
}
}
This follows the DRY principle (Don't Repeat Yourself). A simple example, but it should illustrate the idea.
I used it when I want to pass default or null values to the other constructors. In the case above the user does not have to pass null when calling the constructor-- they can call it with nothing.
public class Widget(){
public Widget() : this(null){
}
public Widget(IRepository rep){
this.repository = rep;
}
}

Categories