Typy generyczne

0

Cześć

Staram się nadrobić wiedzę z typów generycznych i mam kilka pytań:

  1. Mam taki kod:

    {
        static void Main()
        {
            var inty = Metoda1("okon");
            Console.WriteLine(inty);
        }
    
        public static T Metoda1<T>(T zmienna1)
        {
            return zmienna1;
        }
    }

    Teraz chciałem operwoać na konkretnym obiekcie, czyli zrobić coś takiego:

    {
        public Generyki g1;
        static void Main()
        {
            g1 = Metoda2("okon");
        }
    
        public T Metoda2<T>(T zmienna2)
        {
            return zmienna2;
        }

    Kompilator mi na coś takiego nie pozwala, co źle robię?

  2. Drugie pytanie jest związane z pierwszym, chodzi mi o kod ze strony LINK
    Jest tam taka konstrukcja:

    public Rigidbody rb;
    rb = GetComponent<Rigidbody>();
    rb.velocity = new Vector3(0, 10, 0);

    Pierwsza linijka to referejncja do obiektu klasy Rigidbody. Druga to użycie metody GetComponent z zadeklarowanym typem Rigidbody bez podania żadnych parametrów?
    I nie rozumiem czemu trzeba było zrobić w ten sposób, żeby w trzeciej linijce zadeklarować użycie metody Velocity z konkretnym konstruktorem.
    Da się to przedstawić na jakimś prostym przykładzie co się pod tym kryje?

1

Było by prościej jakbyś napisał błąd kompilatora.
Kod:

{
    public String g1;
    static void Main()
    {
        g1 = Metoda2("okon");
    }

    public T Metoda2<T>(T zmienna2)
    {
        return zmienna2;
    }

powinien działać na moją Javową głowę.

UPDATE z poprawkami @Delor:

{
    public static String g1;
    public static void Main()
    {
        g1 = Metoda2("okon");
    }

    public static T Metoda2<T>(T zmienna2)
    {
        return zmienna2;
    }
0
Kamil Żabiński napisał(a):

Taki komunikat dostaję

an object reference is required for the non-static field method or property 'Generyki.g1'

Zastanawiałem się jak użyć typu generycznego z konkretnym obiektym (tak jak to robi dla mnie wrażenie w drugim podpunkcie)

2

Taki komunikat dostajesz, bo przekazujesz niestatyczne pole do statycznej metody.

0
Sarrus napisał(a):

Taki komunikat dostajesz, bo przekazujesz niestatyczne pole do statycznej metody.

{
    public Generyki g1;
    static void Main()
    {
        g1 = Metoda2("okon");
    }

    public T Metoda2<T>(T zmienna2)
    {
        return zmienna2;
    }
}

Metoda też jest niestatyczna.
Chyba, że miałeś na myśli metodą Main. Ale przenosząc wywołanie do innej metody dostaję komunikat:

cannot implicitly convert type 'string' to 'Nauka.Generyki'

2

A to przepraszam. Wywołujesz niestatyczną metodę w statycznej metodzie.

1

Jak chcesz wywołać niestatyczną metodę to najpierw musisz utworzyć obiekt .
Do niestatycznych składowych dostajesz się przez obiekt ( np. nazwa_obiektu.Metoda() albo this.Metoda() )
a do statycznych przez klasę ( nazwa_klasy.Metoda() albo z wnętrza klasy Metoda() )
This i nazwa klasy są automatycznie dodawane przez kompilator C# jeśli wywołujesz składową z wnętrza klasy.

To są podstawy

0

Rzeczywiście macie rację, przy pierwszym podpunkcie popełniłem błąd, bo wrzucałem niestatyczną metodą do statycznej i zignorowałem komunikat kompilatora. Drugiego podpunktu dalej nie rozumiem.
Głównie nie wiem co robi taki zapis:

rb = GetComponent<Rigidbody>();

Do referencji klasy przypisuję wynik metody z podanym typem generycznym Rigidbody? I po co podaję ten typ generyczny kiedy nie używam żadnego parametru? I jak to się ma w dalszej części do tego kawałka kodu:

rb.velocity = new Vector3(0, 10, 0);

Jak wpływa na ten obiekt wywołanie w taki sposób tej etody Rigidbody?

2

Wiesz co ciężko będzie Tobie to wytłumaczyć w kilku zdaniach, bo brakuje Tobie elementarnej wiedzy na ten temat. Forum nie jest od tego, żeby robić wykłady. Postaram się nakreślić Tobie pokrótce:

Weźmy najczęściej wykorzystywaną klasę generyczną jaką jest List<T>. W takiej "surowej" postaci ten typ jest niedomknięty (niepełny). Żeby go użyć potrzebujesz podać parametr np:

var list = new List<int>();

Kompilator utworzy dla Ciebie klasę List<int>. Klasa ta ma metodę void Add(T item), więc w tym przypadku będzie to void Add (int item). Jeżeli napiszesz:

var item = list[0];

item będzie typu int
jeżeli napiszesz

var list = new List<string>();
/* .... */
var item = list[0];

to będziesz miał nową klasę, a item będzie typu string.

0
Sarrus napisał(a):

Wiesz co ciężko będzie Tobie to wytłumaczyć w kilku zdaniach, bo brakuje Tobie elementarnej wiedzy na ten temat. Forum nie jest od tego, żeby robić wykłady. Postaram się nakreślić Tobie pokrótce:

Weźmy najczęściej wykorzystywaną klasę generyczną jaką jest List<T>. W takiej "surowej" postaci ten typ jest niedomknięty (niepełny). Żeby go użyć potrzebujesz podać parametr np:

var list = new List<int>();

Kompilator utworzy dla Ciebie klasę List<int>. Klasa ta ma metodę void Add(T item), więc w tym przypadku będzie to void Add (int item). Jeżeli napiszesz:

var item = list[0];

item będzie typu int
jeżeli napiszesz

var list = new List<string>();
/* .... */
var item = list[0];

to będziesz miał nową klasę, a item będzie typu string.

O typach generyczych czytałem w jednej książce ale ciężko jest mi to przełożyć na ten konkretny przypadek, bo ten kod nie wygląda w ten sposób:

rb = new GetComponent<Rigidbody>();

Czemu tutaj nie muszę jawnie tworzyć nowego obiektu?

Rozumiem, że temat generyków nie jest dobry do omawiania na forum ale jak wspomniałem, czytałem o generykach ale ten przykład jest inny niż ten z którym się spotkałem. Twój przykład do mnie przemawia bo jest podobny do tego, który przerabiałem w książce.

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