I am new to C#. I have a Persons class and a User class which inherits from the Persons class. I my console I input a users in an array. Then I can add a note to a user that is in the users array by only entering the users id. In my Persons class i have this function that has to search if this user is in the users array.
public static Persons FindPerson(Persons[] persons, int noteid)
{
foreach (Persons person in persons)
if (person.ID == noteid) return person;
return null;
}
In my User class I have a function that loops the whole input of the id until it gets an id that is in the users array.
public static User SelectUser(User[] users)
{
while (true)
{
Console.Write("Please enter the User id: ");
string input = Console.ReadLine();
int id;
if (int.TryParse(input, out id))
{
Persons person = Persons.FindPerson(users, id);
if (person != null) return person; // fail on "return person"
}
Console.WriteLine("The User does not exist. Please try again.");
}
}
Everything works fine except that I now get this error message on the "return person" in the if statement.
Cannot implicitly convert type 'UserCustomerNotes.Persons' to 'UserCustomerNotes.User'. An explicit conversion exists (are you missing a cast?)
Can anyone please help? Thanks in advance.
Because a Person
is not nessecarily a User
, the compiler is not able to implicitly convert a Person
to a User
. In your particular case, since you know you have a list of User
s, you can explicitly tell it, "I know this Person
is actually a User
" with the following:
if (person != null)
return (User) person;
The cast ((User)
) will throw an exception at runtime if the instance is not actually a User
, but since you've started with a collection of User
s to begin with, you don't need to worry.
You should rewrite the return snippet like so:
User user = Persons.FindPerson(users, id) as User;
if (user != null) return user;
The problem you were having was to do with you trying to return a base class from a method that should return a more derived class. The compiler cannot automatically downcast(Persons
->User
), but it can upcast (User
->Persons
)
Since User
inherits from Person
, you cannot implicitly convert any random Person
to a User
(though you can implicitly convert a User
to a Person
).
Since you pass a User[]
to FindPerson(users, id)
, you can be sure the returned person is indeed a User
, so you can cast it like this:
return (User)person;
Edit: You might consider using generics on FindPerson
to avoid the cast altogether.
public static T FindPerson<T>(IEnumerable<T> persons, int noteid)
where T : Person
{
foreach (T person in persons)
{
if (person.ID == noteid)
{
return person;
}
}
return null;
}
public static User SelectUser(User[] users)
{
while (true)
{
Console.Write("Please enter the User id: ");
string input = Console.ReadLine();
int id;
if (int.TryParse(input, out id))
{
User person = Persons.FindPerson(users, id);
if (person != null)
{
return person;
}
}
Console.WriteLine("The User does not exist. Please try again.");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With