Не удается неявно преобразовать тип 'customtype' в 'othercustomtype' - PullRequest
7 голосов
/ 21 сентября 2010

Я новичок в C #.У меня есть класс Persons и класс User, который наследуется от класса Persons.Я мою консоль я вводить пользователей в массиве.Затем я могу добавить заметку пользователю, который находится в массиве пользователей, только введя идентификатор пользователя.В моем классе Persons у меня есть эта функция, которая должна искать, находится ли этот пользователь в массиве пользователей.

public static Persons FindPerson(Persons[] persons, int noteid)
{
    foreach (Persons person in persons)
        if (person.ID == noteid) return person;
    return null;
}

В моем классе User у меня есть функция, которая зацикливает весь ввод идентификатора, пока не получитидентификатор, который находится в массиве пользователей.

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.");                
    }
}

Все работает нормально, за исключением того, что теперь я получаю это сообщение об ошибке "return person" в операторе if.

Не могу неявнопреобразовать тип «UserCustomerNotes.Persons» в «UserCustomerNotes.User».Существует явное преобразование (вам не хватает приведения?)

Кто-нибудь может помочь?Заранее спасибо.

Ответы [ 5 ]

12 голосов
/ 21 сентября 2010

Поскольку Person не обязательно является User, компилятор не может неявно преобразовать Person в User. В вашем конкретном случае, поскольку вы знаете , у вас есть список User с, вы можете явно сказать ему: «Я знаю, что Person на самом деле User» со следующим:

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

Приведение ((User)) вызовет исключение во время выполнения, если экземпляр на самом деле не является User, но, поскольку вы начали с коллекции User s, вам не нужно беспокоиться.

4 голосов
/ 21 сентября 2010

Поскольку User наследуется от Person, вы не можете неявно преобразовать любое случайное Person в User (хотя вы можете неявно преобразовать User в Person).

Поскольку вы передаете User[] на FindPerson(users, id), вы можете быть уверены, что возвращенный человек действительно является User, поэтому вы можете разыграть его следующим образом:

return (User)person;

Редактировать: Возможно, вы захотите использовать дженерики на FindPerson, чтобы вообще избежать каста.

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.");                
    }
}
3 голосов
/ 21 сентября 2010

Вам необходимо реализовать явный или неявный оператор:

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"
3 голосов
/ 21 сентября 2010

Вы должны переписать возвращаемый фрагмент следующим образом:

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

Проблема, с которой вы столкнулись, заключалась в том, что вы пытались вернуть базовый класс из метода, который должен возвращать более производный класс.Компилятор не может автоматически понижать (Persons -> User), но он может понижать (User -> Persons)

0 голосов
/ 21 сентября 2010

В любом случае, я рекомендую использовать метод расширения LINQ для вашего первого метода:

using System.Collections.Generic;
using System.Linq;

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

Выглядит намного лучше, верно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...