Zwrócenie typu pochodnej, a nie bazy - jak zrobić?

0

Witam! Napisałem klasę GameObject po której dziedziczą inne obiekty w grze. Mam klasę Player, która właśnie dziedziczy po GameObject. Mam też listę obiektów List<GameObject> objects. Tyle, że ta lista jest obsługiwana przez metodę innej klasy. W tej metodzie zwracam GameObject i przez to nie mam dostępu do pól Player. Jak wykonać rzutowanie czy może coś innego, aby zwróciło mi typ taki jaki jest na danej pozycji w liście. Kod:


        private List<GameObject> objects;

        public GameObject Get(int index)
        {
                return objects[index];
        }

        // --------------------------------

        GameObjectsManager.Get(123).Name // tu mam tylko pola GameObject, a chcę również pola Player

Co mam zrobić, żeby zwracało typ, o którym pisałem wcześniej (typ obiektu z listy o danym indexie)?

0

Przede wszystkim po co Ci to :|. O to właśnie chodzi w dziedziczeniu że traktujesz obiekty jako klasę bazową. Jeśli chcesz rzutować zwrócony typ na Player to tylko na tej klasie będziesz mógł operować i równie dobrze możesz sobie dać spokój z całą tą obiektowością i dziedziczeniem...

Ale żeby nie było że nie piszę na temat:
Klasycznie:

((Player)GameObjectsManager.Get(123)).Name

Z użyciem operatora as:

(GameObjectsManager.Get(123) as Player).Name
0

Możesz użyć metody generycznej, żeby robiła rzutowanie jeszcze przed zwróceniem wartości. Chyba o takie rozwiązanie Ci chodziło.

0

Ale skąd ja mam wiedzieć, że obiekt o indexie 25953 jest akurat np. Player? Równie dobrze to może być Building itd. I ja chcę właśnie pobrać ten obiekt takim jakim jest, a nie GameObject. Być może, że chodzi o to co post wyżej.

A ogólnie to skoro mam nie dziedziczyć każdego obiektu po GameObject to jak mam to zrobić?? Pisać oddzielnie każdą klasę, dla każdego obiektu, ciekawe jak zrobię z tego listę. Może jest jakiś sposób inny, to proszę o jego przedstawienie.

0

Pytanie moje dlaczego to przechowujesz na jednej liście?

Ale skąd ja mam wiedzieć, że obiekt o indexie 25953 jest akurat np. Player? Równie dobrze to może być Building itd. I ja chcę właśnie pobrać ten obiekt takim jakim jest, a nie GameObject.

Jak chcesz mieć obiekt typu player odebrany z listy, to musisz wiedzieć, który to obiekt, albo zaimplementować w tej metodzie generycznej szukanie tego typu obiektów na liście (operator is)
EDIT:
To co tutaj proponuję jest tylko obejściem w przypadku gdy potrzebujesz trzymać te wszystkie obiekty na liście z innego (sensownego) powodu

0

A ogólnie to skoro mam nie dziedziczyć każdego obiektu po GameObject to jak mam to zrobić?? Pisać oddzielnie każdą klasę, dla każdego obiektu, ciekawe jak zrobię z tego listę. Może jest jakiś sposób inny, to proszę o jego przedstawienie.

Powinieneś dziedziczyć, nie masz rzutować. Po co Ci informacja że dany obiekt jest typu Player czy np. EvilDragon? Jeśli potrzebujesz pola Name to dodaj je do klasy bazowej.

0

Ehh.. Myślę, że tak jest w większości gier więc tak zrobiłem. Mam listę obiektów w grze List<GameObject> klasa ma tylko pole i właściwość Name oraz metody abstrakcyjne Update i Draw. Wszystkie inne obiekty dziedziczą po GameObject. Myślałem czy Player'a dziedziczyć czy nie, żeby to było co innego w ogóle, ale postanowiłem dziedziczyć. Walić tego Player'a, bo to jednak trochę inna klasa. Ale co z obiektami np. Building, Vehicle itd. Przecież pojazd będzie miał pola np. prędkość, ilość miejsc itd. I chcę właśnie dostać się do tych pól (czy właściwości) poprzez mój GameObjectManager, który ma listę obiektów i ma metodę Get(int index) i Get(string name), które zwracają obiekt z listy. Jak mam napisać to wszystko, żeby ładnie się dodawało/usuwało/dostawało do tej listy obiektów. Nie zrobię przecież dla każdej klasy Vehicle etc. oddzielnej listy nie? A chcę dostać np. Vehicle (velocity, slots) + pola po GameObject (name) tyle, że jak wyszukuję po nazwie obiektu np. "Mercedes1", to zwraca mi GameObject, a ja chcę typ obiektu, który ma name = "Mercedes1". Czyli wyszukuję "mur_1342" i zwraca mi typ tego obiektu na liście czyli mur to może być building. Panimajesz?

0

Stosując moje obejście to wywołanie wyglądałoby mniej więcej tak:

Vehicle vehicle = objectManager.Get<Vehicle>("Mercedes1");
0

A stosując moje dwa:

Vehicle vehicle = (Vehicle)objectManager.Get("Mercedes1"); 
Vehicle vehicle = objectManager.Get("Mercedes1") as Vehicle;
0

O w sumie dobre, nie pomyślałem (w sumie to chciałem tak zrobić, ale czytaj dalej), że można tak, ale to trochę psuje estetykę ;/ A jak zapobiec teraz, żebym sobie niechcący dał <vehicle>, a pod "Mercedes1" przypadkowo będzie inny typ?

I ogólnie brzydkie rozwiązanie, bo muszę pamiętać, jakiego typu jest to, to i tamto :( Żeby się kurde dało zwykłe Get i zwraca to co powinno ;/ Hehe:

public T Get(int index)
{
    return objects[i] as (object[i].GetType());
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0