Reputation: 2824
Can I have property StudentId
of class StudentRegistered
be the same type as Student.Id
(i.e., byte
) without mentioning byte
in the StudentRegistered
declaration?
I would like to define the Id
type for each derived class of Person
only once in my application. What am I missing?
public class Person<T>
{
public T Id { get; set; }
public string Name { get; set; }
}
public class Student : Person<byte> { }
public class Adult : Person<short> { }
public class StudentRegistered
{
public /* type */ StudentId { get; set; }
public int EventId { get; set; }
}
Edit, to clarify:
Student.Id
's type (i.e., byte
) anywhere outside the Student
declaration. string Name
as a property of StudentRegistered
.Adult
s in StudentRegistered
. A byte
type for StudentRegistered.StudentId
is sufficient.Upvotes: 0
Views: 133
Reputation: 29244
No there is no way to do what you are asking because StudentRegistered
will be two different types, one with byte
for StudentId
and one with short
for StudentId
.
There are serious design issues here by requiring different types for a common ID. Your best choise to have common base interface with a InnerID
method and then link the interfface with the registration.
public interface IPerson
{
ValueType InnerID { get; }
}
public abstract class Person<T> : IPerson
where T : struct
{
public T ID { get; set; }
protected abstract ValueType InnerID { get; }
ValueType IPerson.InnerID { get { return InnerID; } }
}
public class Student : Person<byte>
{
protected override ValueType InnerID
{
get { return ID; }
}
}
public class Adult : Person<short>
{
protected override ValueType InnerID
{
get { return ID; }
}
}
public class StudentRegistered
{
public ValueType StudentID { get { return Person.InnerID; } }
public IPerson Person { get; set; }
public int EventId { get; set; }
}
class Program
{
static void Main(string[] args)
{
var A=new Student() { ID=100 }; // byte
var B=new Adult() { ID=1000 }; // short
var regA=new StudentRegistered() { Person=A };
Console.WriteLine("Type: {0} Value: {1}", regA.StudentID.GetType().Name, regA.StudentID);
// Type: Byte Value: 100
var regB=new StudentRegistered() { Person=B };
Console.WriteLine("Type: {0} Value: {1}", regB.StudentID.GetType().Name, regB.StudentID);
// Type: Int16 Value: 1000
}
}
Upvotes: 1
Reputation: 144106
You'll have to use generics somewhere, you could do:
public class StudentRegistered<TS, TId> where TS : Person<TId>
{
public TId StudentId {get; set;}
public int EventId {get; set;}
}
Upvotes: 0
Reputation: 101680
Yes, you can make it generic and inherit from Person<T>
public class StudentRegistered<T> : Person<T>
{
public T StudentId {get; set;};
public int EventId {get; set;};
}
Upvotes: 1