开发者

Cannot implicitly convert type 'customtype' to 'othercustomtype'

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 Users, 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 Users 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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜