/ / Jak zmienić zmienną polymorphed w typ potomny? - c #

Jak zmienić zmienną polymorphed w typ potomny? - c #

Robię program, który używa polimorfizmu, alena liście. Teraz, gdy używam wartości z listy, już określiłem, które są dziećmi i rodzicami za pomocą instrukcji if, ale problem polega na tym, że nie mam dostępu do żadnych atrybutów podrzędnych. Wszelkie sugestie? (Przykładowy kod poniżej)

//In Class one
public List<Parent> parent;
parent.Add(new Child());


//In Class two
if (parent[0] is Child)
{
//treats it as parent
Console.WriteLine(parent[0].name());
}

W powyższym kodzie nazwa atrybutu jest publicznaale w klasie dziecka, więc nie mogę uzyskać dostępu do żadnego z atrybutów dziecka, ponieważ on nie wie, że jest dzieckiem. Czy istnieje sposób, aby uczynić przedmiot dzieckiem? Lista musi korzystać z polimorfizmu, ponieważ istnieje wiele różnych klas potomnych, które muszą znajdować się na jednej liście.

Odpowiedzi:

1 dla odpowiedzi № 1

Chciałbym użyć as słowo kluczowe. Jest to bezpieczna obsada, która zwraca wartość null, gdy rzutowanie nie jest możliwe.

Child child = obj as Child;
if (child!=null)
{
child.childMethod();
}

0 dla odpowiedzi nr 2

W przypadku dziedziczenia i polimorfizmu odwołanie do obiektu nadrzędnego, które wskazuje obiekt podrzędny, może uzyskać dostęp do metod nadrzędnych w środowisku wykonawczym. Jednak można go obsadzić i wywołać metody Child. ((Child) obj).childMethod();


0 dla odpowiedzi № 3

Możesz uzyskać metody potomne poprzez rzutowanie, w ten sposób:

//In Class one
public List<Parent> parent;
parent.Add(new Child());

//In Class two
Child parentAsChild = parent[0] as Child;
if (parentAsChild != null)
{
Console.WriteLine(parentAsChild.name());
}

The as operator wykonuje rzut obronny, który zwraca wartość null, jeśli parent[0] nie można rzutować na Child obiekt.

Bądź jednak ostrożny - omijaszcelu polimorfizmu w ten sposób. Cały punkt polimorfizmu polega na tym, że nie musisz wykonywać sprawdzania typu i rzucania - klasa potomna powinna zastąpić każde zachowanie różniące się od rodzica.


0 dla odpowiedzi nr 4

Albo rzuć obiekt Child po sprawdzeniu jego typu:

//In Class one
public List<Parent> parent;
parent.Add(new Child());

//In Class two
if (parent[0] is Child)
{
var child = (Child) parent[0];
Console.WriteLine(child.name());
}

lub rzucić obiekt na Child przed sprawdzeniem jego typu:

//In Class one
public List<Parent> parent;
parent.Add(new Child());


//In Class two
var child = parent[0] as Child;
if (child != null)
{
//treats it as parent
Console.WriteLine(child.name());
}

Tego rodzaju odlewania należy unikać, gdy tylko jest to możliwe. Rozważ skorzystanie z interfejsu do zdefiniowania interfejsu API, który musisz skonsumować lub zdefiniowania wirtualnego elementu na Parent.