0

Below you see the ISubject interface. Both partial student_subject and Tutor_subject are are auto generated however these partial classes are used to allow for a parent gemeroc abstract class.

Before I pass student_Subject "sub" into new SubjectDTO(ISubject subject), it has all its properties. For example, sub.name would equal "math".

enter image description here

However, once I pass it to the constructor, SubjectDTO(ISubject subject) all the properties of subject are null.

enter image description here

Sorry If I seem new but does anyone have an idea why the object does not retain its properties. here is the code

 public abstract class  ISubject
{
    public int SubjectId { get; set; }
    public string Name { get; set; }
    public System.Data.Entity.Spatial.DbGeography Location { get; set; }
    public virtual ICollection<ICourse> Courses { get; set; }

}
public partial class Student_Subject :ISubject
{

    public DbSet<Student_Subject> getContext(studytree_dbEntities db)
    { return db.Student_Subject; }

}
public partial class Tutor_Subject :ISubject
{
    public DbSet<Tutor_Subject> getContext(studytree_dbEntities db)
    { return db.Tutor_Subject; }

}

here is the automatically generated class

 public partial class Student_Subject
  {
    public Student_Subject()
    {
        this.Courses = new HashSet<Student_Course>();
    }

    public int SubjectId { get; set; }
    public string Name { get; set; }
    public int Student_CourseId { get; set; }
    public System.Data.Entity.Spatial.DbGeography Location { get; set; }

    public virtual ICollection<Student_Course> Courses { get; set; }
    public virtual Student Student { get; set; }
}
}

Here is my StudentDTO .

    public class StudentDTO
     {
       public StudentDTO()
     {
         this.StudySessions = new HashSet<StudySessionDTO>();
        this.Subjects= new HashSet<SubjectDTO>();
    }
         public StudentDTO(Student s)
    {
        this.StudentId = s.StudentId;
        this.FirstName = s.FirstName;
        this.LastName = s.LastName;

        this.StudySessions = new HashSet<StudySessionDTO>();
        this.Subjects = new HashSet<SubjectDTO>();
             foreach(Student_Subject sub in s.Subjects)
             {
                 this.Subjects.Add(new SubjectDTO(sub));
             }
    }
  }

Subject DTO However when the execution comes to this class, the object has all null properties.

 public class SubjectDTO
 {
       public SubjectDTO()
    {
        this.Courses = new HashSet<CourseDTO>();
    }
    public SubjectDTO(ISubject subject)
       {
           this.SubjectId = subject.SubjectId;
           this.SubjectName = subject.Name;
           this.Location = subject.Location;
           this.Courses = new HashSet<CourseDTO>();
            foreach(ICourse course in subject.Courses)
            {
                this.Courses.Add(new CourseDTO(course));
            }
       }

Here is the exception

An exception of type 'System.NullReferenceException' occurred in StudyTree.dll but was not handled in user code

Additional information: Object reference not set to an instance of an object.

InnerException Object reference not set to an instance of an object.

StackTrace: at StudyTree.Models.SubjectDTO..ctor(ISubject subject) in c:\Users\Ethan\Documents\Visual Studio 2013\Projects\StudyTree\StudyTree\Models\SubjectDTO.cs:line 21 at StudyTree.Models.StudentDTO..ctor(Student s) in c:\Users\Ethan\Documents\Visual Studio 2013\Projects\StudyTree\StudyTree\Models\UserDTO.cs:line 118 at StudyTree.Models.PersonDTO..ctor(Person person) in c:\Users\Ethan\Documents\Visual Studio 2013\Projects\StudyTree\StudyTree\Models\UserDTO.cs:line 31 at StudyTree.Repository.LoginRepository.getPersonDTO(Person p) in c:\Users\Ethan\Documents\Visual Studio 2013\Projects\StudyTree\StudyTree\Repository\LoginRepository.cs:line 41 at MvcApplication2.Controllers.ProfileController.Login(JObject j) in c:\Users\Ethan\Documents\Visual Studio 2013\Projects\StudyTree\StudyTree\Controllers\ProfileController.cs:line 34 at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.b__9(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)

Jämes
  • 6,945
  • 4
  • 40
  • 56
EK_AllDay
  • 1,095
  • 2
  • 15
  • 35

1 Answers1

1

You state you are implementing an interface called ISubject in your classes Student_Subject and Tutor_Subject. Nonetheless, this is not the case, you are truly inherit from an abstract class misnamed ISubject. The prefix I must ONLY be used for interfaces, not for abstract classes.

The issue comes from the fact you think abstract classes react like interfaces.

When implementing an interface, you need, to fulfill its contract, to rewrite all the code inside your class.

When inheriting a class (event from abstract one), you don't have to rewrite the code defined in the superclass.

You actually redefine the property Name in your children classes, that hides the property of the superclass. Visual Studio displays a warning about that.

The keyword new is required on Name because its hides property ISubject.Name.

To correct that, just make a true interface by replacing public abstract class ISubject to public interface ISubject and make the necessary changes in the body of the interface.

Jämes
  • 6,945
  • 4
  • 40
  • 56