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? T开发者_JAVA技巧hanks 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.");
}
}
You need to implement explicit or implicit operator:
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"
Anyway, I recommend to use 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);
}
Looks much better, right?
精彩评论