C
C#2w ago
Ownera

Just learned generics...

I just learned generics and have a problem that i tried googling but still couldnt solve. I have a person class
C#
internal class Person<T> where T : Person<T>
{
public T Name { get; set; }
public T Pass { get; set; }



}
C#
internal class Person<T> where T : Person<T>
{
public T Name { get; set; }
public T Pass { get; set; }



}
C#
internal class User : Person // this is the error.At person, CS0305
{

public string Nameu { get; set; }

public string Passu { get; set; }

}
C#
internal class User : Person // this is the error.At person, CS0305
{

public string Nameu { get; set; }

public string Passu { get; set; }

}
And a user class that i want to inherit the Person class.
11 Replies
Ownera
Ownera2w ago
i am still a very beginner so i might have some easy mistakes in my code
Pobiega
Pobiega2w ago
When inheriting a generic class, you need to specify the generic parameter either by making your child class also be generic and passing the generic, or by setting it concretely your constraint here doesnt really make sense either - you are saying T needs to be a Person<T>
Ownera
Ownera2w ago
oh thats my bad, i meant it to be everything under person
Pobiega
Pobiega2w ago
thats fine in itself, but given that you are using T to make two properties of type T, called "Name" and "Pass(word?)"...
Ownera
Ownera2w ago
but it sends an eror so i thought i had to mention person as the generic in every instance
Pobiega
Pobiega2w ago
internal class Person<T>
{
public T Name { get; set; }
public T Pass { get; set; }
}

internal class User : Person<string>
{
public string Email { get; set; }
}
internal class Person<T>
{
public T Name { get; set; }
public T Pass { get; set; }
}

internal class User : Person<string>
{
public string Email { get; set; }
}
here for example User specifies that T is string for all users so name and pass become public string Name { get; set; } etc for User
Ownera
Ownera2w ago
I think i do get it Yes it worked thank you
Ownera
Ownera2w ago
although in program.cs when i try to create an object and insert the property of name and pass (which is short for password) it seems as if there isnt anything to fill
No description
Ownera
Ownera2w ago
the error is that it doesnt have a constructor to fill in the argument
Pobiega
Pobiega2w ago
so 2 errors here Person<User> seems weird in the first place and second, the compiler is right, you have not made any constructors so there is no ctor that takes in a parameter at all Remember, the T is a "placeholder". whatever you give there replaces all T in the class so Person<User> has a Name property of type User thats pretty weird meaning your structure becomes person.Name.Name if you want to get a users username or person.Pass.Name? we dont know the structure is just very confusing
Clint
Clint2w ago
Yeah looks like you'd be better off avoiding generics for a scenario like this, you're probably better off looking at interfaces for something - similar -. E.g.
public abstract class Person {
public string Name { get; set; }
public string Pass { get; set; }
}

public interface IHasEmail {
public string Email { get; set; }
}

public class User : Person, IHasEmail {
public string Email { get; set; }
}
public abstract class Person {
public string Name { get; set; }
public string Pass { get; set; }
}

public interface IHasEmail {
public string Email { get; set; }
}

public class User : Person, IHasEmail {
public string Email { get; set; }
}
This way you could do something like:
public void SendEmailTo(IHasEmail person, string subject, string body)
{
var address = person.Email;
// do something else here
}
public void SendEmailTo(IHasEmail person, string subject, string body)
{
var address = person.Email;
// do something else here
}
Generics would be useful if your types were immutable e.g.:
public abstract record Person
{
public string Name { get; init; }
public string Pass { get; init; }
}

public interface IHasEmail
{
public string Email { get; init; }
}

public record User : Person, IHasEmail
{
public string Email { get; init; }
}

public T UpdateEmail<T>(T person, string newEmail) where T : IHasEmail
{
return person with {
Email = newEmail
}
}
public abstract record Person
{
public string Name { get; init; }
public string Pass { get; init; }
}

public interface IHasEmail
{
public string Email { get; init; }
}

public record User : Person, IHasEmail
{
public string Email { get; init; }
}

public T UpdateEmail<T>(T person, string newEmail) where T : IHasEmail
{
return person with {
Email = newEmail
}
}
This might not be 100% as just typing it out here, but you could invoke it like this:
var myUser = new User {
Name = "Name",
Email = "[email protected]",
Pass = "test"
};

var myModifiedUser = UpdateEmail(myUser, "[email protected]");
var myUser = new User {
Name = "Name",
Email = "[email protected]",
Pass = "test"
};

var myModifiedUser = UpdateEmail(myUser, "[email protected]");
Want results from more Discord servers?
Add your server