简体   繁体   中英

how to access method in nested class from main - C#

this is editing of my first question: so i checked the assignment again. all code is working as my professor want it to work, but only my question that i asked before is my problem. - how can i execute the method ShowGrade directly from the list (which is course) like: list[1].ShowGrade(0) without using list[1].s.ShowGrade(0) ?? i will put here all my code. the two console lines in the Main is what he want (and how he wants it), my constraints for the assignment were: 1. nested class Student in class Course (one student for course). 2. no constructors at all but the default constructors. 3. the ShowGrade method won't be in the Course class. 4. no operator . (dot) in ShowGrade, only [] 5. in method Q1 will be only one query.

so my code is:

course. cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HW_1
{
    public class Course 
    {
        private delegate int Del(Course c);

        internal string courseName { get; set; }

        public  class Student
        {
            internal string stuName { get; set; }
            internal List<int> gradesList { get; set; }

            //internal int ShowGrade(int index)
            //{
            //    return gradesList[index];
            //}
        }

        internal Student s = new Student();

        public override string ToString()
        {
            string gr = null;
            foreach (var g in s.gradesList)
                gr += g + " ";
            return string.Format("{0, -6} {1, -14} {2, -10}", courseName, s.stuName, gr);
        }

    }
}

Program.cs :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HW_1
{
    class Program
    {
        private delegate bool Del(Course c);

        static void Main(string[] args)
        {
            List<Course> list = new List<Course>
            { 
                new Course {courseName = "C#", s = new Course.Student {stuName = "Jojo", gradesList = new List<int>(){10, 20, 100}}},
                new Course {courseName = "C", s = new Course.Student {stuName = "Bambi", gradesList = new List<int>(){99}}},
                new Course {courseName = "Java", s = new Course.Student {stuName = "Bambi", gradesList = new List<int>(){}}}

            };

            Console.WriteLine("List of courses:");
            Print(list);

            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("Press P / p for students who passed in average 60 and those who didn't.");
            Console.WriteLine("");
            Console.WriteLine("Press # for C# courses and others.");
            Console.WriteLine("");
            Console.WriteLine("Press any other key for courses with student who have at least one grade of 100 and all oter courses.");

            char ch = (char)Console.Read();
            Del d = ((ch == 'P' || ch == 'p') ? (Del)(c => c.s.gradesList.Count > 0 && c.s.gradesList.Average() >= 60) : ((ch == '#') ? (Del)(c => c.courseName == "C#") : (Del)(c => c.s.gradesList.Contains(100))));

            var x = Q1 <IGrouping<bool, Course>>(list, d);
            Print(x);

            Console.WriteLine("");
            //Console.WriteLine(list[1].ShowGrade(0));
            //Console.WriteLine(list[2].ShowGrade(3));

        }

        static IEnumerable<T> Q1<T>(IEnumerable<Course> list, Del d)
        {
            var query =
                from c in list
                orderby d(c)
                group c by d(c) into g
                select g;

            return (IEnumerable<T>)query;
        }

        static void Print(IEnumerable<IGrouping<bool, Course>> list)
        {
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Q1 Results:");
            foreach (var g in list)
            {
                Console.WriteLine();
                Console.WriteLine(g.Key);
                Console.WriteLine("---------------");
                foreach (var c in g)
                    Console.WriteLine(c);
            }
        }

        static void Print<T>(IEnumerable<T> list)
        {
            foreach (var l in list)
                Console.WriteLine(l);
        }



    }
}

the output for the two Console.writeline has to be:

list[1].ShowGrade(0)
99
list[2].ShowGrade(3)

You have a list of courses with students that are exposed as s :

Console.Writeline(list[1].s.ShowGrade(0));

You therefore need to access the s field of list[x] . However, I'd suggest you to use a property instead of the public field:

class Course
{
    internal string c_name {get; set;}
    public Student Student { get; private set; }

    public Course()
    {
        this.Student = new Student();
    }
}

I actually recommend you to create Student as a non-inner class . Inner classes are supposed to be used locally only.

class Student
{
    internal s_name {get; set;}
    internal List<int> gradesList {get; set;}
}

If you want to keep Student as an inner class, you have to make it public in order to use it outside the Course class.

list[n] returns a Course , which has a Student property (one course can have one student?), from where you want to show the grade.

Your Student class needs this method:

public int ShowGrade(int index)
{
   return gradesList[index];
}

Then you can call:

list[n1].s.ShowGrade(n2);

Your code definitely needs to be revised as there are issues ie

new Course ("C#", s.s_name = "Bob", s.gradesList = new List<int>(){100, 99, 85})

won't compile, it seems like you are getting confused with passing constructor parameters & object initialization .

I can't use constructors

You can only use object initialization to some extent, for example, given c_name is public you could do:

var course = new Course()
{
    c_name = "C#"
}

However, you can't do:

var course = new Course()
{
    s.gradeList = ...
}

You just need to manually set this

var course = new Course()
{
    c_name = "C#"
};
course.s.gradeList = new List<int>() { ... }

To answer your question though, I would use a bit of encapsulation here and expose a ShowGrade method in your Course class which would give you the code you want ie

 
 
 
  
  Console.Writeline(list[1].ShowGrade(0));
 
  

Internally, Course would just delegate the call onto the student instance eg

 
 
 
  
  public int ShowGrade(int grade) { return s.ShowGrade(grade); }
 
  

Just realised you said you can't add ShowGrade to the Course class, in that case you just need to access the Student property from the Course ie

  list[0].s.ShowGrade(0); 

The penny just dropped on this one, you need to have the code like:

public static class CourseExt
{
    public static int ShowGrade(this Course course, int grade)
    {
        return course.s.ShowGrade(grade);
    }
}
...
Console.WriteLine(list[0].ShowGrade(0));

but can't modify the Course class - the only alternative is to use an extension method eg

 public static class CourseExt { public static int ShowGrade(this Course course, int grade) { return course.s.ShowGrade(grade); } } ... Console.WriteLine(list[0].ShowGrade(0)); 

Here is the code you asked for:

class Course
{
    internal string CourseName { get; set; }
    public Student s { get; set; }

    public class Student
    {
        internal string StudentName { get; set; }
        internal IEnumerable<int> GradesList { get; set; }

        public int ShowGrade(int index)
        {
            if (GradesList == null)
                throw new NullReferenceException();
            return GradesList.ElementAt<int>(index);
        }
    }
}


class Program
{
    static void Main(string[] args)
    {
        List<Course> list = new List<Course>()
    {
        new Course () { CourseName = "C#", 
            s =  new Course.Student() { StudentName = "Bob", 
                                                                            GradesList = new List<int>() { 100, 99, 85 }}},  
        new Course () { CourseName = "Java", 
            s =  new Course.Student() { StudentName = "Bobi", 
                                                                            GradesList = new List<int>(){ 99, 90, 88 }}},
        new Course (){ CourseName = "C", 
            s = new Course.Student() { StudentName = "Roni", 
                                                                            GradesList = new List<int>()}},
        new Course (){ CourseName = "SQL", 
            s = new Course.Student() { StudentName = "Sean", 
                                                                            GradesList = new List<int>(){ 75, 62, 55 }}}
    };
        Console.WriteLine(list[0].s.ShowGrade(1));

        Console.ReadKey();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM