• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Typy generyczne

Object Storage Arubacloud
0 głosów
700 wizyt
pytanie zadane 4 maja 2019 w C# przez Shimeo7 Obywatel (1,910 p.)

Cześć, zacząłem typy generyczne, poczytałem o nich trochę, porobiłem jakieś proste przykłady, ale natrafiłem na problem z przykładem do rozwiązania, gdzie mam poprawić kod tak, aby mógł się skompilować, siedzę na tym od kilku h, kombinuje i klops. Czy ktoś mógłby mi powiedzieć/podpowiedzieć co należy zrobić, aby kod się skompilował? 

class Program
    {
        public static T GetObjectOrNull<T>(bool getNull)
        {
            if (getNull)
            {
                return null;
            }
            else
                return new Tr();
        }

        static void Main(string[] args)
        {
            Tr tr;
            GetObjectOrNull<T>(true);
        }
    }

Tr tr -> to jest obiekt tr klasy Tr, który utworzyłem, gdyż myślałem, że to pomoże. Próbowałem rzutowani, też nie działa. Błąd jest z nullem i utworzeniem nowego obiektu Tr z bloku else.Z góry dziękuję za pomoc. 

komentarz 10 maja 2019 przez aeragram Obywatel (1,760 p.)
edycja 10 maja 2019 przez aeragram
Cześć,

Jeżeli dobrze zrozumiałem to powyższy kod został przez ciebie trochę zmieniony względem oryginalnej treści zadania ? Jak wyglądała oryginalna treść zadania ?

Pozdrawiam aeragram

3 odpowiedzi

–1 głos
odpowiedź 4 maja 2019 przez adrian17 Ekspert (344,860 p.)
wybrane 5 maja 2019 przez Shimeo7
 
Najlepsza

Zakładając że gdzieś wyżej jest konkretna klasa Tr:

public class Tr
{
  // stuff
}

Argumentem szablonu powinien być już konkretny typ, więc:

GetObjectOrNull<Tr>(true);
GetObjectOrNull<List<int>>(true);
// etc

A metoda powinna pewnie zwracać argument typu, który sobie zażyczyliśmy, więc nie

return new Tr();

tylko

return new T();

Wtedy kod ma sens. Kompilator wciąż rzuca dwa błędy, ale są już dość czytelne i mówią jak je poprawić.

komentarz 5 maja 2019 przez Shimeo7 Obywatel (1,910 p.)
w zasadzie to mam tylko metodę statyczną, gdzie jest wyżej instrukcja warunkowa, klasa Tr jest wymyslona przeze mnie. Ja muszę stwierdzić, dlaczego kod w metodzie się nie kompiluje oraz co muszę zrobić, aby był poprawny.
komentarz 5 maja 2019 przez adrian17 Ekspert (344,860 p.)

w zasadzie to mam tylko metodę statyczną, gdzie jest wyżej instrukcja warunkowa, 

No tak.

klasa Tr jest wymyslona przeze mnie

OK, ale rozumiem że to jest jakaś konkretna klasa która faktycznie istnieje gdzieś w kodzie (`public class Tr`).

Ja muszę stwierdzić, dlaczego kod w metodzie się nie kompiluje oraz co muszę zrobić, aby był poprawny.

Moja odpowiedź na to znajduje się powyżej ;)

komentarz 5 maja 2019 przez Shimeo7 Obywatel (1,910 p.)

Racja, czasami mam problemy z czytaniem ze zrozumieniem. Wykombinowałem takie coś. Zmieniłem nazwę klasy Tr na Objecy (dla swojej czytelności), w klasie nie ma absolutnie nic.

A kod programu tak się prezentuje, wydaje się działać.

class Program
    {
        public static Objecy GetObjectOrNull<Objecy>(bool getNull) where Objecy : new()
        {
            if (getNull)
            {
                return default(Objecy);           
            }
            else
            {
                return new Objecy();
            }                
        }

        static void Main(string[] args)
        {
            Console.WriteLine(GetObjectOrNull<Objecy>(false).ToString());
            Console.ReadKey();
        }
    }

 

komentarz 5 maja 2019 przez adrian17 Ekspert (344,860 p.)

No i to już prawie to (dla konwencji polecam jednak pisać T zamiast `Objecy`, cokolwiek to znaczy), tylko z jedną zasadniczą rzeczą jest problem:

GetObjectOrNull<Objecy>(false).ToString()

Jak już wywołujesz generyczną metodę, to chcesz już dostać w wyniku rzecz *konkretnego* typu. `Objecy` był tylko argumentem szablonu, tutaj musisz przekazać już jakiś faktyczny argument do tego szablonu.

+1 głos
odpowiedź 10 maja 2019 przez aeragram Obywatel (1,760 p.)

Cześć,

Jeżeli oryginalna treść zadania wyglądała tak:

public static T GetObjectOrNull<T>(bool getNull)
{
    if (getNull) return null;
    else return new T();
}

to rozwiązaniem problemu jest dodanie ograniczeń typu generycznego w taki sposób:

public static T GetObjectOrNull<T>(bool getNull) where T:class,new()
{
    if (getNull) return null;
    else return new T();
}

Dlaczego ?

Po pierwsze typ <T> może być dowolnym typem, a to oznacza, że może być też typem wartościowym (np. integer), który nie może przyjmować wartości null, dlatego kompilator widzi błąd dla 'return null'. Żeby temu zapobiec możemy ograniczyć typy generyczne wyłącznie do typów referencyjnych używając 'where T:class'.

Po drugie typ <T> jako dowolny typ, może posiadać prywatny konstruktor co powoduje, że próba utworzenia instancji typu <T> zakończy się niepowodzeniem (bo nie widzimy konstruktora i nie możemy wykonać 'new T()' ). Rozwiązaniem tego problemu jest użycie dodatkowo 'where T:new()', co ogranicza typy generyczne do takich, które posiadają publiczny bezparametrowy konstruktor. 

Warto przeczytać ten tekst.

Pozdrawiam aeragram

0 głosów
odpowiedź 5 maja 2019 przez piotrsz109 Stary wyjadacz (13,730 p.)

Możesz podać przy definicji metody możesz podać

where T:Tr

 

Podobne pytania

0 głosów
0 odpowiedzi 244 wizyt
pytanie zadane 3 czerwca 2019 w C# przez rubesom Obywatel (1,690 p.)
0 głosów
1 odpowiedź 596 wizyt
pytanie zadane 4 maja 2017 w C# przez Jakub Gonera Nowicjusz (140 p.)
0 głosów
1 odpowiedź 266 wizyt
pytanie zadane 12 listopada 2018 w Java przez Patryk01 Obywatel (1,270 p.)

92,575 zapytań

141,425 odpowiedzi

319,650 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...