Cannot implicitly convert type 'customtype' to 'othercustomtype'

I am new to C #. I have a Person class and a User class that inherits from the Person class. I have my console inject users into an array. Then I can add a note to the user in the users array by just entering the user ID. In my Persons class, I have this function that should look for whether this user is in an array of users.

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 processes all the input of the identifier until it gets the identifier 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 now I get this error message in the "returned person" in the if statement.

It is not possible to implicitly convert the type 'UserCustomerNotes.Persons' to 'UserCustomerNotes.User'. Explicit conversion exists (are you skipping listing?)

Can anybody help? Thanks in advance.

+4
source share
5 answers

Since a Person does not matter User , the compiler cannot implicitly convert a Person to User . In your particular case, since you know that you have a User s list, you can directly tell him: β€œI know that this Person is actually a User ” with the following:

 if (person != null) return (User) person; 

Casting ( (User) ) will throw a runtime exception if the instance is not really User , but since you started with the User collection to get you started, you needn't worry.

+11
source

Since User inherits from Person , you cannot implicitly convert any random Person to User (although you can implicitly convert a User to Person ).

Since you pass User[] to FindPerson(users, id) , you can be sure that the returning person is indeed User , so you can do it like this:

 return (User)person; 

Edit: You can use generics on FindPerson to avoid casting 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."); } } 
+4
source

You should rewrite the returned fragment as follows:

 User user = Persons.FindPerson(users, id) as User; if (user != null) return user; 

The problem you are having is that you are trying to return a base class from a method that should return a more derived class. The compiler cannot automatically turn off ( Persons β†’ User ), but it can raise ( User β†’ Persons )

+3
source

You need to implement an explicit or implicit statement:

 class ClassA { public string Property1 { get; set; } public static explicit operator ClassB(ClassA classA) { return new ClassB() { Property2 = classA.Property1 }; } } class ClassB { public string Property2 { get; set; } } var a = new ClassA() {Property1 = "test"}; ClassB b = (ClassB)a; Console.WriteLine(b.Property2); // output is "test" 
+1
source

In any case, I recommend using the LINQ extension method for your first method:

 using System.Collections.Generic; using System.Linq; public static Persons FindPerson(IEnumerable<Person> persons, int id) { return persons.FirstOrDefault(p => p.ID == id); } 

It looks much better, right?

0
source

All Articles