Kan type ‘customtype’ niet impliciet converteren naar ‘othercustomtype’

Ik ben nieuw in C#. Ik heb een klasse Personen en een klasse Gebruikers die erven van de klasse Personen. Op mijn console heb ik een gebruiker in een array ingevoerd. Dan kan ik een notitie toevoegen aan een gebruiker die zich in de gebruikersreeks bevindt door alleen de gebruikers-ID in te voeren. In mijn Persons-klasse heb ik deze functie die moet zoeken of deze gebruiker in de gebruikersarray staat.

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

In mijn gebruikersklasse heb ik een functie die de hele invoer van de id in een lus plaatst totdat deze een id krijgt die in de array van gebruikers staat.

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

Alles werkt prima, behalve dat ik nu deze foutmelding krijg op de “return person” in de if-statement.

Kan het type ‘UserCustomerNotes.Persons’ niet impliciet converteren naar ‘UserCustomerNotes.User’. Er bestaat een expliciete conversie (mis je een cast?)

Kan iemand me alsjeblieft helpen? Bij voorbaat dank.


Antwoord 1, autoriteit 100%

Omdat een Personniet noodzakelijk een Useris, kan de compiler niet impliciet een Personconverteren naar een User. In jouw specifieke geval, aangezien je weetdat je een lijst met Users hebt, kun je expliciet zeggen: “Ik weet dat deze Personfeitelijk een User” met het volgende:

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

De cast ((User)) zal tijdens runtime een uitzondering genereren als de instantie niet echt een Useris, maar aangezien u bent begonnen met een verzameling van Users om mee te beginnen, u hoeft zich geen zorgen te maken.


Antwoord 2, autoriteit 24%

Je moet het return-fragment als volgt herschrijven:

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

Het probleem dat u had, had te maken met het feit dat u een basisklasse probeerde te retourneren van een methode die een meer afgeleide klasse zou moeten retourneren. De compiler kan niet automatisch downcasten (Persons->User), maar wel (User->Persons)


Antwoord 3, autoriteit 24%

Aangezien Usererft van Person, kunt u niet impliciet een willekeurige Personconverteren naar een User(hoewel u kan impliciet een Userconverteren naar een Person).

Aangezien u een User[]doorgeeft aan FindPerson(users, id), kunt u er zeker van zijn dat de geretourneerde persoon inderdaad een Useris , dus je kunt het als volgt casten:

return (User)person;

Bewerken:u kunt overwegen generieke geneesmiddelen te gebruiken op FindPersonom de cast helemaal te vermijden.

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

Antwoord 4, autoriteit 18%

U moet een expliciete of impliciete operator implementeren:

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"

Antwoord 5

Hoe dan ook, ik raad aan om de LINQ extension-methode te gebruiken voor je eerste methode:

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

ziet er veel beter uit, toch?

Other episodes