C
C#•3y ago
big OOF

Declare method using T and where [Answered]

This is some code from a reddit post i saw and there are some thing i dont understand. This is the method:
public static T CreateStudentFromEntity<T>(Student entity) where T : IStudent
{
var student = Activator.CreateInstance<T>();

student.Id = entity.Id;
student.FirstName = entity.Name;
student.Surname = entity.Surname;
student.DateOfBirth = DateTime.Parse(entity.DateOfBirth);
student.Sex = (Sex)entity.Sex;
student.Address = CreateAddressFromEntity(entity.Address);

return student;
}
public static T CreateStudentFromEntity<T>(Student entity) where T : IStudent
{
var student = Activator.CreateInstance<T>();

student.Id = entity.Id;
student.FirstName = entity.Name;
student.Surname = entity.Surname;
student.DateOfBirth = DateTime.Parse(entity.DateOfBirth);
student.Sex = (Sex)entity.Sex;
student.Address = CreateAddressFromEntity(entity.Address);

return student;
}
This is the interface that the method uses:
public interface IStudent
{
long Id { get; set; }
string? FirstName { get; set; }
string? Surname { get; set; }
DateTime DateOfBirth { get; set; }
Sex Sex { get; set; }
string? TelephoneNumber { get; set; }
Address? Address { get; set; }
}
public interface IStudent
{
long Id { get; set; }
string? FirstName { get; set; }
string? Surname { get; set; }
DateTime DateOfBirth { get; set; }
Sex Sex { get; set; }
string? TelephoneNumber { get; set; }
Address? Address { get; set; }
}
From what i understand, T is used to be able to make the method more "flixble", not restricting it to a specific return type. But when adding "where T : IStudent" - it restricts it to only return a object that inherits the IStudent interface? Could you not just replace T with IStudent and skip the where? Plase let me know if i got in wrong 🙂 Thanks in advance!
15 Replies
Kouhai
Kouhai•3y ago
using a constraint like this is 1 - faster 2 - allows you to have concrete return type Let's say you have an implementation of IStudent like this
public class InternationalStudent : IStudent
{
long Id { get; set; }
string? FirstName { get; set; }
string? Surname { get; set; }
DateTime DateOfBirth { get; set; }
string PlaceOfBirth {get; set;}
Sex Sex { get; set; }
string? TelephoneNumber { get; set; }
Address? Address { get; set; }
}
public class InternationalStudent : IStudent
{
long Id { get; set; }
string? FirstName { get; set; }
string? Surname { get; set; }
DateTime DateOfBirth { get; set; }
string PlaceOfBirth {get; set;}
Sex Sex { get; set; }
string? TelephoneNumber { get; set; }
Address? Address { get; set; }
}
the returned value from CreateStudentFromEntity<InternationalStudent>(entity) would be of InternationalStudent and you can access PlaceOfBirth without casting
Pobiega
Pobiega•3y ago
Very well explained. This is because of how generics work behind the scenes - the compiler will look at the different types you pass in and actually make a "copy" of the method that works with that specific type.
Unknown User
Unknown User•3y ago
Message Not Public
Sign In & Join Server To View
big OOF
big OOFOP•3y ago
Okey, thank you for the answer! Just to get my head around it - Could you say that the use of T in this case is to make a method avalible using multiple classes? And the where to restrict it to specific classes?
Kouhai
Kouhai•3y ago
Yes, where here is used to restrict T to IStudent implementers. In the first place, you can't instantiate an interface, so you have to use a class. If you take a look at the code ToBeClone provided, they added another constraint new() this ensures that the caller has passed a class/struct implementing IStudent
Unknown User
Unknown User•3y ago
Message Not Public
Sign In & Join Server To View
big OOF
big OOFOP•3y ago
Okok! Antother question regarding new(), i would like to say that:
where T : IStudent, new()
where T : IStudent, new()
requires a class that implements IStudent interface and new() interface - but new() isnt an interface. Is it instead - it require a the caller to pass an object that can be instantiated? 🙂 Sorry if im asking the same questions over and over, a bit new to this :p
Unknown User
Unknown User•3y ago
Message Not Public
Sign In & Join Server To View
big OOF
big OOFOP•3y ago
Okey! So new() set the restriction to only accept an object that includes a parameterless contructor? 🙂
Kouhai
Kouhai•3y ago
Yes, it accepts a type that has a parameterless constructor
Unknown User
Unknown User•3y ago
Message Not Public
Sign In & Join Server To View
Kouhai
Kouhai•3y ago
they didn't say redirections, they said restriction 😅
Unknown User
Unknown User•3y ago
Message Not Public
Sign In & Join Server To View
big OOF
big OOFOP•3y ago
Haha no worries! Thank you guys for the great help, really appriciated 🙂
Accord
Accord•3y ago
✅ This post has been marked as answered!
Want results from more Discord servers?
Add your server