Kilka podstawowych pytań dotyczących metod

0

Witajcie.

Mam kilka pytań na początek, jestem nowy, proszę o wyrozumiałość.

  1. Co robią instrukcje:
this.SuspendLayout();
this.ResumeLayout(false);
this.PerformLayout();
  1. Dlaczego w poniższym kodzie na textbox1 nie zmienia się wyświetlana liczba - przecież inkrementuję ją w zdarzeniu kliknięcia przycisku oraz odświeżam kontrolkę textbox:
 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public class Form1 : Form
    {
        public int wsk;

        public Form1()
        {
            InitializeComponent();
        }

        private Button button1;
        private Button button2;
        private TextBox textBox1;

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            //
            // button1
            //
            this.button1.Location = new System.Drawing.Point(98, 50);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            //
            // button2
            //
            this.button2.Location = new System.Drawing.Point(98, 153);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(75, 23);
            this.button2.TabIndex = 1;
            this.button2.Text = "button2";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Paint += new System.Windows.Forms.PaintEventHandler(this.button2_Paint);
            //
            // textBox1
            //
            this.textBox1.Location = new System.Drawing.Point(89, 206);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 2;
            this.textBox1.Text = wsk.ToString();
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(292, 266);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private void button1_Click(object sender, EventArgs e)
        {
            wsk++;
            textBox1.Refresh();
        }

        private void button2_Paint(object sender, PaintEventArgs e)
        {

        }

    }

}
  1. Dlaczego w obsłudze zdarzenia metoda Invalidate() odświeża całą formę a nie tylko przycisk.
    Jak zrobić żeby odświeżeniu uległ jedynie przycisk?
 private void button1_Click(object sender, EventArgs e)
        {
            // odświeżenie kontrolki Form a nie button'a
            Invalidate();
        }

A i jeszcze jedno drobne pytanie :
W metodzie obsługi zdarzenia formatki .Paint mam napisane :

private void Form1_Paint(object sender, PaintEventArgs e)
        {
            //Invalidate();
           
            wsk += 10;
            Graphics g = e.Graphics;
            g.DrawRectangle(Pens.Red, 5, 5, 7, wsk);
        } 

W chwili gdy za "DrawRectangle" dopisuję instrukcję :

 g.Dispose();

to generowany jest błąd po uruchomieniu projektu - VS wskazuje na Application.Run i wypisuje że "parametr jest nieprawidłowy". Skąd ten błąd się bierze ? Przecież w literaturze czytałem że utworzone obiekty typu Graphics można a nawet należy usunąć po "narysowaniu".

dodanie znacznika <code class="csharp"> - furious programming

2
  1. Zmienna nie ma stałego połączenia z TextBoxem, raz ją przypisałeś, a potem zmieniając liczbę, nie jest nowa wartość przypisywana do TextBoxa, musisz ją ponownie przypiać
  2. Ponieważ wywołujesz ją wewnątrz klasy Form1 , robiąc Invalidate() robisz this.Invalidate(), czyli Form1.Invalidate(). Nie ma znaczenia to, że wpisujesz to w zdarzeniu od Buttona, musiałbys zrobić button1.Invalidate();
0

Dziękuję za odpowiedzi.
Zrozumiano :)

A da się jakoś zrobić żeby zmienna właśnie takie połączenie z tekstboxem miała na stałe aby nie robić tego ciągłego przypisania.
Chodzi o to aby zmiana zmiennej skutkowała wyświetleniem od razu innej zawartości. Jakie sugestie ? Odświeżanie / przypisanie / może coś innego ?

Jeśli chodzi o moje ostatnie pytanie z poprzedniego posta to wycofuję bo w między czasie znalazłem odpowiedź.
Przechwytując obiekt graficzny w zdarzeniu nie można go niszczyć gdyż jest on przecież wykorzystywany również przez inne rzeczy w programie stąd ten runtime wyjątek.

Czy mogę mieć nadzieję na stałe wsparcie w programowaniu w c#. Zabrałem się do tego ostro i raz na jakiś czas potrzebuję zmasowanej pomocy.

1

Najprosciej, dodaj do tej klasy Form1 property i na niej operuj, a nie na zmiennej bezposrednio. Następnie w property w setterze oprócz przypisania nowej wartości, aktualizuj textboxa.

0

Jasna sprawa. Jeszcze raz dzięki za wskazówki.
A nie można zrobić czegoś takiego żeby przypisać właściwość textbox1.Text do jakiegoś wskaźnika wskazującego na daną zmienną.
Strzelam teraz - proszę o podpowiedź.
Wskaźniki mam raczej dobrze rozpracowane i potrafię się nimi posługiwać - ważna jest strategia w tym momencie bo nie chcę tracić czasu jeśli i tak się tak jak myślę nie będzie dało.

1
Adamos19 napisał(a):

A nie można zrobić czegoś takiego żeby przypisać właściwość textbox1.Text do jakiegoś wskaźnika wskazującego na daną zmienną.

Właściwość TextBox.Text jest typu string. Nie możesz do niej przypisać na stałe wartości typu int, bo to inny typ danych, musisz najpierw skonwertować na string. A string to typ immutable, każda modyfikacja tej samej zmiennej typu string powoduje tak naprawdę powstanie nowej zmiennej w innym miejscu pamięci, więc żadne wskaźniki nic nie pomogą (nawet, gdyby dało się ich w taki sposób w C# użyć).

Czemu tak bardzo przeszkadza Ci, że musisz na nowo przypisać do TextBoxa wartość, która się zmieniła? To trochę tak jakbyś chciał prać jednorazowe chusteczki do nosa.

0

Bardzo dziękuję za odpowiedź. Naprawdę w późniejszym czasie jak zostanę dobrym będę i ja pomagał - obiecuję.
Generalnie zadając takie pytania dostaję odpowiedzi na których niezwykle dużo się uczę i po to je zadaję.
Nie mówię że tak nie będę robić - po prostu teoretycznie pytam, chcę wiedzieć.

Pociągnę jednak to pytanie dalej i zapytam o to co by się stało gdyby jakaś właściwość jakiejś kontrolki była typu int.
Co by się stało gdybym wpisał wskaźnik do innej zmiennej typu int właśnie w miejsce tejże właściwości i manipulowałbym (bez żadnego dodatkowego przypisania) wartością wspomnianej zmiennej. Czy wówczas zmianie ulegałaby również wartość właściwości kontrolki ?

Czym właściwie jest owe "przypisanie" zmiennej przechowującej określoną wartość do właściwości i dlaczego to tak jest że po jej zmianie nie zmienia się również właściwość tylko trzeba znowu przypisać ?

Proszę jeszcze raz o komentarz, zdaję sobie sprawę z tego że to pytanie może nie mieć praktycznego sensu jednak pomimo to proszę o odpowiedzi.

1
Adamos19 napisał(a):

Pociągnę jednak to pytanie dalej i zapytam o to co by się stało gdyby jakaś właściwość jakiejś kontrolki była typu int.
Co by się stało gdybym wpisał wskaźnik do innej zmiennej typu int właśnie w miejsce tejże właściwości i manipulowałbym (bez żadnego dodatkowego przypisania) wartością wspomnianej zmiennej. Czy wówczas zmianie ulegałaby również wartość właściwości kontrolki ?

Po pierwsze, jeśli coś jest typu int, to nie przypiszesz do niego typu wskaźnik do int. Właściwość musiałaby też być wskaźnikiem na int. No i nawet gdybyśmy tak to zrobili, to zmiana wartości tej zmiennej, nawet gdyby była "widziana" przez obiekt kontrolki nie musi wcale oznaczać zmiany tego, co widzimy na ekranie.

Po pierwsze pamiętaj, że właściwości to nie są pola lecz metody. A zatem we właściwości można napisać dowolny kod i dowolnie reagować na przypisywaną wartość, więc można ją też zupełnie zignorować.

Po drugie, C# to nie C++, tu są typy wartościowe i referencyjne, a ze wskaźników używa się tylko w specyficznych przypadkach takich jak korzystanie z zewnętrznych natywnych bibliotek i API. Do tego cały kod korzystający ze wskaźników musi być w sekcji unsafe, a kod trzeba kompilować w specjalnym trybie zezwalającym na korzystanie ze wskaźników.

Czym właściwie jest owe "przypisanie" zmiennej przechowującej określoną wartość do właściwości i dlaczego to tak jest że po jej zmianie nie zmienia się również właściwość tylko trzeba znowu przypisać ?

Gdyby właściwości automagicznie śledziły życie każdej zmiennej do nich przypisanej, program wymagałby ogromnych zasobów do działania.

Tak czy siak, jestem zaskoczony, że początkujący rozmyśla o takich sprawach i zadaje takie nietypowe pytania.

0

Jeszcze raz dzięki wielkie za komentarz.
Gorące pozdrowienia.

PS. A co w tym takiego dziwnego ? Chciałbym po prostu dobrze wszystko zrozumieć, po Twoim poście jestem znowu bliżej prawdy :D

Zamykam temat.

Tylko jak tutaj się zamyka tematy ? Jakaś szybka podpowiedź ?

1
Adamos19 napisał(a):

PS. A co w tym takiego dziwnego ? Chciałbym po prostu dobrze wszystko zrozumieć, po Twoim poście jestem znowu bliżej prawdy :D

Większość początkujących próbuje robić wszystko bez zrozumienia, dlatego Twoje podejście jest dziwne. ;)

Tylko jak tutaj się zamyka tematy ? Jakaś szybka podpowiedź ?

Trzeba kliknąć w przycisk "Zablokuj wątek" w menu po prawej (poniżej "Obserwuj wątek"), musisz być co najmniej moderatorem działu, aby móc to zrobić.

1

Tematów się zazwyczaj nie zamyka, tylko oznacza jako rozwiązane. Ale czasami może się pojawić ktoś, kto ma jeszcze coś do dodania... na przykład teraz.

W WPF i WinRT naturalne jest użycie mechanizmu "data binding", który działa nieco tak jak byś chciał - do kontrolki jestem w stanie dowiązać zmienną (de facto: pole klasy), i kiedy zmienna zmienia swoją wartość, to jest to odzwierciedlane w kontrolce. I może też być zrobione w drugą stronę - kiedy zmieniam wartość w kontrolce, zmienia się wartość zmiennej. Nie operuje to jednak na prostych wskaźnikach i nie śledzi automatycznie zmian w zmiennych, ale wymaga własnoręcznego zaimplementowania takiego mechanizmu poprzez implementację interfejsu INotifyPropertyChanged.

Możesz sobie przejrzeć: http://msdn.microsoft.com/en-us/library/ef2xyb33%28v=vs.90%29.aspx ale niekoniecznie jest to temat dla początkujących w C#.

0

Jeszcze raz dzięki.
Mam jeszcze jedno pytanie tak na szybko.

Załóżmy że mam klasę w której zdefiniowałem pole typu string.
Załóżmy też że tworzę później kilka obiektów tejże klasy nadając w konstruktorze odpowiednie wartości temu polu string.
Następnie tworzę listę do której dodaję referencje do tych obiektów.

ArrayList al = new ArrayList();
al.Add(o1);
al.Add(o2);
al.Add(o3);

I pytania :

  1. Czy aby na pewno w kolejnych elementach listy będą przechowywane referencje do obiektów czy może właśnie te obiekty ?
    Słyszałem że arraylist.add przyjmuje jako parametr object, co oznacza że chcąc wkładać obiekty tam automatycznie dokonuje się opakowywanie w typ object.
  2. Jak teraz sortować tą listę alfabetycznie po tym polu typu string?

Próbowałem robić tak aby klasa dziedziczyła po IComparable, zaimplementowałem w niej metodę int CompareTo(klasa other) jednak nie dało to rezultatu. Program nie chce sortować listy i wywala błąd. Jakieś sugestie ?

  1. Mając dwa stringi string s1,s2; Jak określić który byłby pierwszy przy sortowaniu alfabetycznym.
    Czy dopuszczalna jest instrukcja if (s1>s2) {;} ?

dodanie znaczników <code class="csharp"> i `` - furious programming

0
Adamos19 napisał(a):
  1. Czy aby na pewno w kolejnych elementach listy będą przechowywane referencje do obiektów czy może właśnie te obiekty ?
    Słyszałem że arraylist.add przyjmuje jako parametr object, co oznacza że chcąc wkładać obiekty tam automatycznie dokonuje się opakowywanie w typ object.

Przechowuje referencje. Co do Arraylist - tak przechowuje referencje obiektów jako klasy object. Dlatego są kolekcje generyczne i ArrayList się nie używa.

Np. klasa List<string> przechowuje referencje stringów a nie object i nie ma boxing i unboxing.

  1. Jak teraz sortować tą listę alfabetycznie po tym polu typu string?

Jeżeli koniecznie na ArrayList to robisz:

            string o1 = "zasa";
            string  o2 = "asfdafs";
            string o3 = "sbfdafsa";
            ArrayList al = new ArrayList();
            al.Add(o1);
            al.Add(o2);
            al.Add(o3);
            al.Sort();
            foreach (var z in al)
            {
                Debug.WriteLine(z);
            }
  1. Mając dwa stringi string s1,s2; Jak określić który byłby pierwszy przy sortowaniu alfabetycznym.
    Czy dopuszczalna jest instrukcja if (s1>s2) {;} ?

Nie

0

OK, dzięki za wyjaśnienie.
Co do przechowywania przez ArrayList referencji do wstępnie (i automatycznie) opakowywanych obiektów typu "object" to nie mam pytań, w chwili gdy dodaję nie stringi lecz obiekty kompilator opakowuje mi moje obiekty i tworzy z nich object których referencje wrzuca do kolekcji. To rozumiem.

Ciągle jednak nie wiem w jaki sposób posortować listę moich obiektów (zaimplementowałem w klasie interfejs IComparable i metodę CompareTo) ale nic to nie dało. Lista która w moim przypadku przechowuje referencje do object powstałych poprzez opakowanie obiektów mojego własnego typu (przechowujących pole string) nie daje się posortować.
W skrócie : nie chodzi mi o sortowanie typów "string" tylko obiektów, a kluczem po którym sortowanie ma nastąpić jest porządek alfabetyczny pola string tych obiektów.

Być może zły interfejs zaimplementowałem....

Dodatkowo ponawiam pytanie : jak z dwóch stringów string s1,s2; wybrać ten który będzie pierwszy w porządku alfabetycznym ?

Z góry dzięki za odp.

1

Przeanalizuj poniższy kod:

using System;
using System.Collections;
using System.Diagnostics;


    class Program
    {
        static void Main(string[] args)
        {
            var sth1 = new SomeObject("jjjjjj", 10);
            var sth2 = new SomeObject("aaaaa!", 30);
            var sth3 = new SomeObject("bbbb!", 40);

            var someList = new ArrayList();
            someList.Add(sth1);
            someList.Add(sth2);
            someList.Add(sth3);
            Debug.WriteLine("nieposortowana");
            foreach (var z in someList)
            {
                Debug.WriteLine(((SomeObject)z).Name);
            }
            someList.Sort();
            Debug.WriteLine("posortowana");
            foreach (var z in someList)
            {
                Debug.WriteLine(((SomeObject)z).Name);
            }

        }
    }

    class SomeObject : IComparable
    {
        public string Name { get; set; }
        public int Value { get; set; }

        public SomeObject(string name, int value)
        {
            Name = name;
            Value = value;
        }

        public int CompareTo(object obj)
        {
        
            return this.Name.CompareTo(((SomeObject)obj).Name);
        }
    }

Jeżeli chcesz inne typy porównań (wielkość liter, długość stringu itp) wykorzystać, odsyłam do String.Compare().
Zrób sobie analogiczny przykład na List<SomeObject> i zobaczysz kiedy unikniesz rzutowania.

Edit: mały chochlik.

0

Hej.

Dziękuję uprzejmie, zrozumiałem dużo, dla mnie dużo, jednakże prosiłbym o sprawdzenie poprawności poniższych tez które wnioskuję z przykładu (tego i tego który sobie zrobiłem zgodnie z poleceniem kolegi) :

  1. Po dodaniu do ArrayList obiektów dowolnego typu, obiekt ArrayList przechowuje referencje do obiektów typu object
  2. W chwili gdy chcemy wyciągnąć wartość jakiegoś pola to wówczas musimy rzutować element kolekcji na dany typ
  3. Po dodaniu do List<SomeObject> obiektów tego typu, obiekt List przechowuje obiekty naszego typu
  4. W chwili gdy chcemy wyciągnąć wartość jakiegoś pola to wówczas mamy do niego bezpośredni dostęp gdyż nie pracujemy na referencjach tylko na konkretnych obiektach (sprawdziłem i rzeczywiście, ale czy mój wniosek jest słuszny ?)
  5. Z powyższego wynikałoby że proces rzutowania musi zajść właśnie w przypadku gdy chcemy mieć dostęp do pola obiektu a dysponujemy jedynie jego referencją.
  6. Słówko var oznaczać może (jak widać z tego że kompilator to łyka wszystko) dowolny typ wyprowadzony z object, dlaczego więc nie możemy napisać zamiast var - object. Kto jest w stanie opisać różnice pomiędzy var a object przy deklaracji typu.
  7. Kolega użył "var" celowo abym miał mniej do poprawiania w programie i abym dostrzegł gdzie tkwi potrzeba rzutowania, czy tak ?

Mam kilka dodatkowych pytań.

  1. Co robi "debug.writeline" - gdzie to niby wypisuje , na ekranie debugowania jakimś ? Gdzie dokładnie ?
1
Adamos19 napisał(a):
  1. Po dodaniu do ArrayList obiektów dowolnego typu, obiekt ArrayList przechowuje referencje do obiektów typu object

Tak.

  1. W chwili gdy chcemy wyciągnąć wartość jakiegoś pola to wówczas musimy rzutować element kolekcji na dany typ

Tak.

  1. Po dodaniu do List<SomeObject> obiektów tego typu, obiekt List przechowuje obiekty naszego typu
  2. W chwili gdy chcemy wyciągnąć wartość jakiegoś pola to wówczas mamy do niego bezpośredni dostęp gdyż nie pracujemy na referencjach tylko na konkretnych obiektach (sprawdziłem i rzeczywiście, ale czy mój wniosek jest słuszny ?)

"Pracujemy" na referencjach. Jedyna różnica, że typy generyczne (wygooglujesz sobie) pozwalają przechowywać kolekcje jakiś obiektów bez rzutowania na object.

  1. Kolega użył "var" celowo abym miał mniej do poprawiania w programie i abym dostrzegł gdzie tkwi potrzeba rzutowania, czy tak ?
    </qutote>
    Var użyłem z lenistwa. Co znaczy var: http://stackoverflow.com/questions/4307467/what-does-var-mean-in-c

Mam kilka dodatkowych pytań.

  1. Co robi "debug.writeline" - gdzie to niby wypisuje , na ekranie debugowania jakimś ? Gdzie dokładnie ?

Debug wypisuje wynik w oknie output w Visual Basic (alt+2). Zamiast tego możesz użyć oczywiście Console. Oczywiście jak nie wiesz co oznacza klasa/metoda naprawdę google i msdn są najlepsze.

0

Rzeczywiście, zgadza się.
Typy generyczne zalecają stosować bo zwiększają wydajność (nie ma konieczności rzutowania), mamy bezpieczeństwo typów i predefiniowane kontenery list. Już łapię. A my "pracujemy" na referencjach, dlatego że w zasadzie zawsze na nich pracujemy (bo na czym jak nie na bitach mamy pracować...) - przecież w C# wszystko jest obiektem. Ale miło :)

Ale nurtuje mnie jedna rzecz. Korzystając z okazji chciałbym zapytać:

Jeśli deklaruję pole w klasie :
int x;
To w chwili kiedy tworzę obiekt tej klasy to obiekt ten posiada zainicjalizowane to pole na zero.
Dlaczego tak się dzieje że nawet gdy w konstruktorze nie ma x=0 to i tak pole zostaje zainicjalizowane.

Czytałem że w chwili gdy normalnie piszemy :
int x; to środowisko alokuje jedynie pamięć na stosie
int x=0; to alokuje i zapisuje zero
int x=new int(); to alokuje i zapisuje również zero

To dlaczego tak jest że jeśli w klasie mam
int x;
To w chwili gdy tworzę obiekt to wówczas przypisuje się tam zero od razu ?

Dzięki Wielkie za podpowiedzi! Od razu lżej.

0

I ostatnia rzecz na dziś :

Zadeklarowałem typ enum Miesiąc {Styczeń,Luty,...,Grudzień}
Teraz chciałbym wypisać za pomocą odpowiedniej metody typu enum wszystkie miesiące po kolei.
No i doczytałem się że robi się to tak:

foreach (var x in Enum.GetValues(typeof(Miesiąc)))
{ Console.WriteLine(x.ToString()); } 

Chciałbym teraz zapytać o funkcję : typeof(Miesiąc) - co to dokładnie robi ?
Łopatologicznie i w tym samym poście coraz bardziej skomplikowanie jeśli sytuacja tego wymaga proszę :) Żeby było lżej :D

0

Ostatnia odpowiedź FourFour bardzo cenna, wyjaśnia sprawę i koniec.
Nie pisze jak to jest zrobione ale że jest i koniec, i bardzo dobrze ;)
Przyjmuję do wiadomości.

Liczę na odp na ostatniego posta.

0

Dobra , nie było pytania.
Muszę częściej korzystać z MSDN.

Dzięki Wielkie za podpowiedzi. Przyjdę jeszcze pewnie z nieco bardziej skomplikowanymi gdyby tak MSDN mnie zawiódł. :)

Pozdrawiam
Adam

3
Adamos19 napisał(a):

Mam jeszcze jedno pytanie tak na szybko.

Więc czemu nie założysz nowego tematu?

@Adamos19, @mkr, nieźle tu namieszaliście, więc teraz koniec nieścisłości i nieporozumień:

Po pierwsze, to w C# możliwe są obiekty dwóch typów (upraszczam, bo nie chcę mieszać interfejsami i wskaźnikami): wartościowe i referencyjne. Te pierwsze są przekazywane przez wartość, te drugie przez referencję. Jeśli masz referencję, to masz obiekt, pracując na referencji pracujesz na obiekcie. Z punktu widzenia listy, jeśli umieszczasz w niej obiekty typu referencyjnego, to przechowuje ona referencje, jeśli typu wartościowego, to wartości.

Co za tym idzie, jeśli jakaś metoda wymaga typu object, to zanim wstawimy tam typ wartościowy musi on zostać do object przekształcony. To przekształcenie nazywa się opakowaniem (boxing). Przekształcenie w drugą stronę to rozpakowanie (unboxing).

A zatem dodając obiekt typu wartościowego (czyli enum albo struct, z takich bardziej popularnych to np. int, long, bool) do ArrayList zachodzi opakowanie. Jeśli dodajemy obiekt typu referencyjnego, to żadne rzutowanie nie zachodzi, bo każdy typ referencyjny (czyli deklarowany jako class) dziedziczy z object. A jak wiemy za każdy argument metody typu A możemy podstawić dowolny typ dziedziczący z A, więc po co tu coś rzutować?

Dlatego właśnie ten przykład:

mkr napisał(a):

Np. klasa List<string> przechowuje referencje stringów a nie object i nie ma boxing i unboxing.

jest z czapy, bo w przypadku ArrayList, do którego dodamy string nie zajdzie żaden boxing.

W przypadku List<T> oczywiście żadne rzutowanie ani pakowanie nie zachodzi. Jeśli to będzie lista typu referencyjnego, to korzystając z jej elementów będziemy korzystali z referencji, jeśli wartościowego, to z konkretnych wartości.

Adamos19 napisał(a):
  1. Z powyższego wynikałoby że proces rzutowania musi zajść właśnie w przypadku gdy chcemy mieć dostęp do pola obiektu a dysponujemy jedynie jego referencją.

Jeśli dysponujesz referencją typu object, a chciałbyś mieć dostęp do pól, metod i właściwości konkretnej klasy to musisz rzutować na konkretny typ. O ile to nie jest typ wartościowy, bo wtedy trzeba go odpakować, a nie rzutować.

mkr napisał(a):
Adamos19 napisał(a):
  1. Po dodaniu do ArrayList obiektów dowolnego typu, obiekt ArrayList przechowuje referencje do obiektów typu object

Tak.

W przypadku typów referencyjnych, ArrayList przechowuje referencje do takiego typu, jaki został dodany, tyle tylko że sama używa do tego typu object.
W przypadku typów wartościowych wszystko, co jest dodawane jest opakowywane w object przez kompilator, bo argumentów tego typu wymaga metoda Add.

"Pracujemy" na referencjach. Jedyna różnica, że typy generyczne (wygooglujesz sobie) pozwalają przechowywać kolekcje jakiś obiektów bez rzutowania na object.

Na referencjach pracujemy w przypadku typów referencyjnych, natomiast w przypadku wartościowych na wartościach.
Nie ma czegoś takiego jak rzutowanie na object. Albo coś jest object z definicji, albo może zostać w niego opakowany.

Odpowiedzi na pozostałe pytania z wątku:

  1. Mając dwa stringi string s1,s2; Jak określić który byłby pierwszy przy sortowaniu alfabetycznym.
    Czy dopuszczalna jest instrukcja if (s1>s2) {;} ?

W przypadku string nie, ale w swojej klasie możesz zaimplementować taki operator.

  1. Słówko var oznaczać może (jak widać z tego że kompilator to łyka wszystko) dowolny typ wyprowadzony z object, dlaczego więc nie możemy napisać zamiast var - object. Kto jest w stanie opisać różnice pomiędzy var a object przy deklaracji typu.

To nie jest deklaracja typu lecz zmiennej.
Jeśli zadeklarujesz zmienną jako object, to będzie ona właśnie takiego typu. Jeśli użyjesz var, to kompilator sam wywnioskuje jakiego ona jest typu na podstawie tego, co znajduje się po prawej stronie operatora przypisania. To może być object, ale zazwyczaj nie jest.
I var nie ogranicza się tylko do tego, co dziedziczy z object.

Adamos19 napisał(a):

przecież w C# wszystko jest obiektem.

Nie, to tylko głupia plotka. Interfejsy nie są, wskaźniki nie są, jeszcze parę rzeczy nie jest.

Ale nurtuje mnie jedna rzecz. Korzystając z okazji chciałbym zapytać:

A to już jest pytanie na trzeci wątek...

0

No i zajefajnie. Właśnie o takie wytłumaczenie mi chodziło. Co wcale nie znaczy że poprzednikom nie jestem również wdzięczny.
Do usłyszenia niebawem. Pozdrawiam serdecznie!

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