Click here to Skip to main content
16,016,623 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Following is my implementation,

C#
interface iStudent
    {
        Int32 StudentID { get; set; }
    }

    class GraduateStudent : iStudent
    {
        Int32 _PassingoutYear;
        public Int32 PassingoutYear { get { return _PassingoutYear; } set { _PassingoutYear = value; } }
    }

    class CurrentStudent : iStudent
    {
        Int32 _EnrolmentYear;
        public Int32 EnrolmentYear { get { return _EnrolmentYear; } set { _EnrolmentYear = value; } }
    }


Usage: Want to create a generic collection which can store both CurrenStudent and GraduateStudent and should support implicit cast to the objects from the generic collection elements at design time.

So for example,
C#
AllStudents.Add(new CurrentStudent());
AllStudents.Add(new GraduateStudent());
//Should throw compiler warning, since the underlying type is Current Student.
GraduateStudent grad1 = (GraduateStudent)AllStudents[0];
//Should not throw compiler warning, since the underlying type is GraduateStudent Student.
GraduateStudent grad1 = (GraduateStudent)AllStudents[1];


Is this doable? Please note; the generic collection should be type safe and should not allow wrong conversions at design time.
Posted
Updated 7-Apr-10 8:07am

No, there is no way to do what you want and prevent invalid casts at compile time. The generic collection will have to be for some base class or the IStudent interface in order to be able to contain both CurrentStudent and GraduateStudent objects, so the compiler has no way of knowing which derived type an object in the collection might be at compile time.
 
Share this answer
 
The way I normally aproach this is to create an enum with a member for each type and an abstract class that has this type set in the constructor. Often the interface can be removed and the properties etc placed in the abstract class, but if not the abstract class can implement the interface.

Something like:
C#
enum StudentType
{
    Graduate,
    Current
}
interface IStudent
{
    int StudentID { get; set; }
}
abstract class StudentBase : IStudent
{
    private StudentType studentType;
    private int studentID;

    internal StudentBase(StudentType studentType)
    {
        this.studentType = studentType;
    }

    public virtual int StudentID
    {
        get { return studentID; }
        set { studentID = value; }
    }
    StudentType StudentType
    {
        get { return studentType; }
    }
}
class GraduateStudent : StudentBase
{
    int passingoutYear;

    GraduateStudent()
        : base(StudentType.Graduate)
    { }

    public int PassingoutYear
    {
        get { return passingoutYear; }
        set { passingoutYear = value; }
    }
}
class CurrentStudent : StudentBase
{
    int enrolmentYear;

    CurrentStudent()
        : base(StudentType.Current)
    { }

    public int EnrolmentYear
    {
        get { return enrolmentYear; }
        set { enrolmentYear = value; }
    }
}


[Added]
AllStudents would need to be a collection of StudentBase for example List<StudentBase>
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900