NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Inicializace proměnných

V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
beats.omni
Člen
Avatar
beats.omni:25.8.2015 8:22

Jaký je rozdíl v tom, jestli proměnnou inicializuju přímo nebo až v konstruktoru, když přes konstruktor neposílám žádné parametry?

Například

namespace NejakyNamespace
{
    public class NejakaTrida
    {

        string promenna;
        List<string> mujList;

        public NejakaTrida()
        {
                promenna = "Ahoj";
                mujList = new List<string>()
        }
    }
}

vs.

namespace NejakyNamespace
{
    public class NejakaTrida
    {
        string promenna = "Ahoj";
        List<string> mujList = new List<string>();

        public NejakaTrida()
        {
        }
    }
}
 
Odpovědět
25.8.2015 8:22
Avatar
Odpovídá na beats.omni
Neaktivní uživatel:25.8.2015 8:34

Ahoj, když to napíšeš mimo metodu má k tomu přístup celá třídá, zato uvnitř metody je to jen promněná pro metodu, a když ji chceš měnit z jiné metody, tak ti to nepůjde... Snad tomu rozumíš :)

Nahoru Odpovědět
25.8.2015 8:34
Neaktivní uživatelský účet
Avatar
beats.omni
Člen
Avatar
Odpovídá na Neaktivní uživatel
beats.omni:25.8.2015 8:35

Ahoj, tady jsme se asi nepochopili. Já se ptám na inicializaci přes konstruktor nebo mimo něj. Pokud si všimneš, tak ta metoda má stejný název jako třída, takže se jedná o konstruktor a na to se právě ptám :-)

 
Nahoru Odpovědět
25.8.2015 8:35
Avatar
Odpovídá na beats.omni
Neaktivní uživatel:25.8.2015 8:45

Promiň, jak je ráno tak je pro mě těžký i číst, ale myslím že v tom žádný zásadní rozdíl není, jen jde o přehlednost.

Nahoru Odpovědět
25.8.2015 8:45
Neaktivní uživatelský účet
Avatar
Odpovídá na beats.omni
Neaktivní uživatel:25.8.2015 16:54

Pokud se v konstruktoru nemění hodnota v závislosti na parametrech, tak se inicializuje při deklaraci. Rozdíl v tom není, je to jen pro přehlednost

Nahoru Odpovědět
25.8.2015 16:54
Neaktivní uživatelský účet
Avatar
hitzoR
Člen
Avatar
hitzoR:25.8.2015 22:41

Nevím jak v tomhle funguje C#, ale v PHP by při statickém volání nějaké metody nebyla ta proměnná k dispozici, kdyby si ji inicializoval v konstruktoru.

 
Nahoru Odpovědět
25.8.2015 22:41
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na hitzoR
Jan Vargovský:25.8.2015 22:47

Žádná instanční proměnná není nikdy přístupná v statickém kontextu.

 
Nahoru Odpovědět
25.8.2015 22:47
Avatar
dobrakmato
Člen
Avatar
Odpovídá na beats.omni
dobrakmato:25.8.2015 22:50

Nie je v tom ziaden rozdiel. Povedal by som, ze kompilator vsetky priradenia hodnot mimo konstruktoru nakoniec aj tak strci do konstruktoru. Mozes to skusit zostavit a dekompilovat s ILSpy, ci je to naozaj tak.

@Marek Frydrych: Na tom nie je nic specialne. Staticke metody triedy zvycajne nevidia instance premenne.

 
Nahoru Odpovědět
25.8.2015 22:50
Avatar
Odpovídá na dobrakmato
Neaktivní uživatel:26.8.2015 2:34

No, rozdíl v tom sice není (jak jsem říkal), ale pochybuji, že to kompilátor strčí do konstruktoru. Ale nekontroloval jsem to

Nahoru Odpovědět
26.8.2015 2:34
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Patrik Valkovič:26.8.2015 6:54

Vytváření má dvě fáze. Konstruktor se přece nestará o vytvoření paměti pro třídu a podobné věci. Před vytvořením konstruktoru se teda musí vytvořit objekt. V takovém výkladu tedy konstruktor můžeme spíše považovat za metodu, která objekt změní do požadované podoby, než že jej vytvoří.prostě regulérní metodu, poue volanou implicitně.
Čistě teoreticky by měla být inicializace mimo konstruktor pokud je to možné. Vytvoří se v první fázi a měla by být tedy rychlejší.
Jestli to tak je nevím, otázka jak sám překladač kód optimalizuje, jak se optimalizuje při kompilaci atd atd.

Nahoru Odpovědět
26.8.2015 6:54
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
Jakub Lásko[Saarix]:26.8.2015 6:59

Taky bych se přiklonil k tomu, že to hodí kompilátor do konstruktoru.
Přece jen jsou to instanční proměnné a instanci vytváříš pomocí konstruktoru a inicializace se vždy provádí v konstruktoru, takže bych řekl, že to kompilátor provede v rámci konstruktoru.

Viz:

// The default constructor has no parameters. The default constructor
// is invoked in the processing of object initializers.

Object initializer by to pak asi měl pořešit. :-)

Nahoru Odpovědět
26.8.2015 6:59
Časem je vše možné.
Avatar
Odpovídá na Patrik Valkovič
Jakub Lásko[Saarix]:26.8.2015 7:01

Hm zajimavé, na tom něco bude. Zajimalo by mě, jestli není někde uvedeno jak to opravdu je :-) Bylo by to zajimavé vědět jak s tím pracují.

Nahoru Odpovědět
26.8.2015 7:01
Časem je vše možné.
Avatar
dobrakmato
Člen
Avatar
dobrakmato:26.8.2015 13:51

No zostavil som si jednoduchy program a potom ho dekompiloval z IL.

class Program
{
    int a = 4;

    public Program() {
    }

    public Program(int b) {
        this.a = b;
    }

    static void Main()
    {
        Program p = new Program();
        p = new Program(6);
    }
}

Vyzera to tak, ze kompilator vytvori nejaku .ctor():void metodu, ktora sluzi ako konstruktor.

Jej telo bolo taketo:

.ctor():void

// Program
private int a = 4;
public Program()
{
}

.ctor(int):void

// Program
private int a = 4;
public Program(int b)
{
        this.a = b;
}

Cize by sme mohli povedat, ze ich kompilator zaroven strcil a aj nestrcil do konstruktoru. S istotou vieme podla tohoto povedat, ze deklaracie sa priradia skor, ako sa zacne vykonavat konstruktor triedy.

Ako je to so super konstruktormi neviem, bolo by fajn, ak by sa vyjadril niekto, kto ma vacsie skusenosti s .NET a IL ako ja a popripade ma poopravil s tym ako to v skutocnosti je. :D

Editováno 26.8.2015 13:52
 
Nahoru Odpovědět
26.8.2015 13:51
Avatar
Patrik Valkovič:26.8.2015 22:23

Jak mě na to ještě dnes přišla později myšlenka, napadlo mě pár řešení.
Podívat se do IL - už bylo řešeno a moc chytří z toho teda nejsme
S projektem Roslyn přišel i kompilátor do stavu OpenSource - bohužel kompilátor kompiluje pouze do IL, takže i kdyby ses v něm vyznal (o čemž pochybuji), zřejmě bys nezjistil nic nového než z IL (ale možná jo, kdo ví).
Napsat na MSDN fórum - třeba dostaneš odpověď.

Ale optimalizace na takové úrovni už je so hardcore. Pokud nevytváříš tisíce (spíše milióny) instancí, nepoznáš rozdíl. Z jednoduché optimalizace algoritmu dostaneš stejný efekt, jak z tohoto případu.

Nahoru Odpovědět
26.8.2015 22:23
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
coells
Tvůrce
Avatar
Odpovídá na Patrik Valkovič
coells:26.8.2015 23:08

... nebo si jednoduše přečteš specifikaci C#, kde je to vysvětlené. C# 5.0 spec, kapitola 10.11.2
Také se můžeš dozvědět, že konstruktor není metoda a není potřeba ho vytvářet, což ostatně platí pro libovolnou metodu třídy.

 
Nahoru Odpovědět
26.8.2015 23:08
Avatar
Jirka Kaja
Člen
Avatar
Odpovídá na beats.omni
Jirka Kaja:28. května 9:39

Ahoj, no pokud to dobře chápu, konstruktor je platný jen při startu třídy a proměnné v něm aktivované nejsou použitelné v celé třídě. Pokud tedy chceš proměnnou používat, je potřeba ji mít v konstruktoru a následně do konstruktoru přiřadit hodnotu do proměnné třídy.

class XY
{
 int autoTrida;

         public XY()
         {
                int autoKonstruktor = 5;
                this.autoTrida = autoKonstruktor;
        }
}

hodnota z konstruktoru se přiřadí do proměnné třídy...

 
Nahoru Odpovědět
28. května 9:39
Avatar
JerryM
Člen
Avatar
JerryM:1. srpna 7:58

v podstatě v tom není žádný rozdíl .... spíš asi záleží na tom jestli ta tvoje proměnná je lokální v konstruktoru nebo ne ... pokud je, tak už nebude dostupná v celé třídě. ale je logičtější inicializace proměnné v konstruktoru - pokud je taková proměnná globální v celé třídě . mužeš mít i více konstruktorů. konstruktor muže být i prázdný a inicializaci proměnné mužeš dělat v nějaké soukromé metodě ...

 
Nahoru Odpovědět
1. srpna 7:58
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 17 zpráv z 17.