Kilka podstawowych pytań dotyczących metod

Kilka podstawowych pytań dotyczących metod
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

Witajcie.

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

  1. Co robią instrukcje:
Kopiuj
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:
Kopiuj
 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?
Kopiuj
 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 :

Kopiuj
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ę :

Kopiuj
 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

edytowany 3x, ostatnio: flowCRANE
MI
  • Rejestracja:ponad 15 lat
  • Ostatnio:prawie 9 lat
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();
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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.

MI
  • Rejestracja:ponad 15 lat
  • Ostatnio:prawie 9 lat
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.

Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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.

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około godziny
  • Lokalizacja:Wrocław
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.

edytowany 1x, ostatnio: somekind
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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.

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około godziny
  • Lokalizacja:Wrocław
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.

Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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ź ?

spartanPAGE
tematów się nie zamyka
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około godziny
  • Lokalizacja:Wrocław
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ć.

Ktos
Moderator
  • Rejestracja:prawie 23 lata
  • Ostatnio:około 8 godzin
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#.

somekind
ale niekoniecznie jest to temat dla początkujących w C#. - właśnie dlatego o tym nie pisałem. No i to w sumie nie tyle data binding, bo to było od zawsze, lecz MVVM.
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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.

Kopiuj
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

edytowany 2x, ostatnio: flowCRANE
flowCRANE
Wstawiaj kod w znaczniki kolorujące składnię;
MK
Tę listę, a nie tą listę.
MK
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 10 lat
  • Postów:33
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:

Kopiuj
            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


Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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.

MK
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 10 lat
  • Postów:33
1

Przeanalizuj poniższy kod:

Kopiuj
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.


edytowany 6x, ostatnio: mkr
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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 ?
MK
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 10 lat
  • Postów:33
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.


edytowany 1x, ostatnio: mkr
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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.

Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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:

Kopiuj
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

Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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.

Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około godziny
  • Lokalizacja:Wrocław
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...

edytowany 1x, ostatnio: somekind
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
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!

somekind
Tylko błagam, nowe pytania w nowym wątku. :)
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)