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

Tvůrce

Zobrazeno 50 zpráv z 54.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Silně typovaný = vždy uváděj typy. Var nemá smysl - ani u páce s databázemi - vždy se dá uvést typ...
Já vidím používání var hlavně ve WIndows 8 aplikacích a to přímo u
programů od Microsoftu. Pochopil jsem, že pokud nevíš přesně co
potřebuješ za typ, nevíš co přesně metoda vrací (víš že soubor , ale
nevíš do čeho to uložit) , tak použiješ var. Ale stále mi přijde
hezčí, přehlednější používat a rozlišovat typy
Kdepak - to víš vždy před kompilací - s vhodným IDE stačí jen najet nad problémové místo a je...
Ještě:
var v JS je skoro zbytečný - jediný rozdíl mezi C# je, že v C# je 100% zbytečný. var v JS použiješ jen při definici globální proměnné - aby se k ní dalo přistupovat z různých objektů, jinak není potřeba...
I když teď si říkám, jestli v JS také není zbytečný úplně...
Var NENÍ proměnná bez typu. Var se překládá už v době kompilace a kompilátor si tam sám doplní typ, kterého ta proměnná je.
Pokud chcete mít proměnnou, do které byste nacpali cokoliv, tak se na to používá typ Object...
Matěji, ty kecko, keyword "var" samozřejmě je zbytečný, celý C# je zbytečný jakož i .NET a OOP jsou zbytečné. Totiž úplně všechno nad instrukční sadou procesoru je zbytečné.
Nevím, jestli třeba víš co je to LINQ. Srovnej si
IQueryable<MyNamespace.MyClass> items = ...
vs.
var items = ...
Var v C# opravdu N E N Í totéž co var v JS. Var v C# má typ, který jednoznačně určuje inicializace. Samozřejmě nejde udělat:
var x = null;
ani
var x = "Matej je tele";
x = 255;
Brisingře, klidně var používej všude kde to jde, oddálíš si karpální tunel a ušetříš na klávesnicích, jinak nic jinak než bez varu nebude.
Btw. Object tedy ehm ehm taky není zrovna "proměnná do které byste nacpali cokoliv". Je to prostě proměnná typu object. Že je zrovna všechno v .NETu zděděné ze System.Object je fakt, ale obdoba JS "var" je v C# "dynamic". V čem je rozdíl pochopí ti, kteří se podívají na pojmy boxing a unboxing.
Dynamic umí až MSVS 2010, já ještě používám 2008
Ale to ještě neznamená, že se proměnná typu object dá nějak srovnávat s dynamickým typem.
Strkej si to své mámě - takhle do mě furt jebat. Já LINQ používám. Uvaruj se třeba k smrti - dělej si prase kód - jak chceš. Já se chci ve svém kódu vyznat...
Jsi idiot, když si myslíš, že nevím, co je var v C#. Kde jsem psal, že var v C# == var v JS??? Ne - nepsal. Srovnej si to v palici!
Hele - ty si třeba maž hovna na vlasy, ale urážej jen lidi, které znáš.
Psal jsi to tady:
"... var v JS je skoro zbytečný - jediný rozdíl mezi C# je, že v C# je 100%
zbytečný ..."
Var v C# používají jen jelita, která neví, jakého typu bude výsledek operace.
Var vznikl kvůli LINQu. Zaprvé z něj lezou někdy opravdu příšerné
typy, zadruhé si z DB můžu vytahat data do anonymního typu. Anonymní typ
samozřejmě ve finále typ také má, ale opravdu bys ho nechtěl deklarovat
Tak tento argument se mi líbí mnohem víc. Nese informační hodnotu.
Bavil jsem se o významové hodnotě - ne o významu. Chytej mne za co chceš, var nepoužívám ani v LINQ - ale tam ho klidně budu akceptovat - však jinde opravdu ne.
Matýsku už ti bohužel nerozumím. Tento vybraný slovník ses naučil ve speciální škole pro předčasně vyspělé dětičky?
Pokud jsi tím svým postem nemyslel, že je var v C# totéž co var v JS, tak bohužel krom programování neumíš ještě psát.
No, jinak, může tady nějaký odpůrce keywordu "var" uvést nějaký argument proti? Teda krom toho, že ho používají jen jelimani? Ještě jsem nenarazil na situaci, kdy bych kvůli var nějak nechápal kód, a to ho používám opravdu hodně. Jak ví i Mates, normální IDE mi v nejhorším případě umí typ proměnné ukázat, takže problém je jen v odmítání všeho nového?
Var vzniklo hlavně kvůli anonymním typům, kde je zadat explicitně typ poněkud obtížné. Používat ho v běžném kódu je minimálně matoucí, to ostatně praví i oficiální MSDN. Všimni si, že tam ho v ukázkových kódech najdeš jen na místech, kdy je to nutné. C# je silně typovaný jazyk s určitými konvencemi, asi uznáš, že nahradit:
string s = "text";
za
var s = "text";
Není nejlepší nápad. Když to není nutné, nemá tam var co dělat.
Deklarace (definice) primitivních datových typů není asi ten
nejvhodnější příklad, kde použít var, tam bych se tomu taky asi vyhnul,
tam si člověk toho psaní moc neušetří.
Ale když mi třeba funkce vrací něco jako Dictionary<int,
List<string>> tak v použití varu pro uložení výsledku nevidím
naprosto žádný problém.
Proč by neměl být nejlepší nápad používat místo string x = "abc"; rovnocennou variantu var x = "abc"; ? Je na to nějaký argument, krom toho, že se ti to nelíbí?
Ty používáš k vývoji programů IDE? Jak odvážné!
Nepochopil jsem...
Podle mě si var můžeš dávat kam chceš, když víš co děláš. Problém nastane, když si k programu sedne někdo jiný a má ho pak číst. Skoro nemožné, pokud tam máš skoro všude var. Celkově to pak snižuje šanci pochopit kód, když se k němu vrátíš později.
Ale to je furt řečí a argument nikde... Děláme to takhle už několik let a nic takového nepozorujem. Na cestě k pochopení cizího/mého starého kódu jsou úplně jiná úskalí, než podle levé strany deklarace vidět typ proměnné. Přece já stejně jako kompiler vidím pravou stranu, tj. pokud už mám na očích deklaraci, je mi jasné, jakého typu proměnná bude. Nehledě na to, že jsem nikdy neměl ambice frajeřit v komerční sféře bez moderního IDE, takže v nejhorším vidím typ proměnné při najetí kurzorem.
Ti, kteří mají pocit, že pro přehlednost programu je klíčová takováhle zřejmost typu, by měli striktně dodržovat maďarskou notaci. A dělá to dnes někdo v C#? Moc ne. Potože to má pro zpřehlednění kódu minimální přínos, mnohdy spíš negativní.
Chtěl bych tě vidět, jak pomocí anonymního typu s VAR uděláš
globalní proměnou.
Sice se GP nemají příliš používat kvůli šetření paměti, ale někdy
jsou potřeba a s VAR se můžeš jít akorát zahrabat.
VAR používám jen u LINQu.
Chtěl bych taky troškou do diskuze . Myslím, že používání var , tuple
přináší do kódu zmatek a hlavně nepřehlednost. Také je zdrojem velmi
nepříjemných chyb .
Není totiž jedno zda napíšeme var x = 1; nebo var x = 1.0;
Pokud někdo z Vás používal ReSharper 8.0 a nejste pozorní přepíše
všechny definované typy na var typy. Potom se divíte . Třída Tuple<T>
vnese do programu pěkný zmatek , protože každý programátor je líný tvor
málo se píší komentáře a po nějakém čase se v programu nevyzná ani
autor. Lepší je typ dynamic jedná se o statický typ je zkoumán za běhu
programu. Dá se s ním ušetřit dosti psaní , na příklad chceme načítat v
programu Excel a neznáme verzi zákazníckého Excelu.
Zkoušel jsem Code Contracts a dostal jsem se do šílených programových
konstrukcí ,
sám jsem přestal chápat co jsem napsal .
PZ
Neznáš základy ?
Globální proměnou deklaruješ přímo v třídě, mimo metody a je
přístupná ve všech metodách v dané třídě, kde byla deklarovaná. V
paměti zaniká až při ukončení aplikace.
Lokální proměnná je použitelná jen v metodě, kde byla deklarovaná a při
ukončení metody se zruší i v paměti.
To je field (instanční proměnná), C# nic jako globální proměnnou nemá, protože je to moderní objektový jazyk.
Tak jí říkám globální a co ? Je to sice pojem z C, ale pro programátora má stejnou funkci. Nehraj si zase se slovíčky. Stejně jsi nevěl, že VAR jako instanční použít nejde.
Pokud jsi myslel instanční proměnnou v C++ u třídy, tak to je něco
úplně jiného než globální proměnná
Taktiež si povedal, že tvoja "globálna premenná" zaniká pri ukončení aplikácie, čo je tiež blbosť podľa mňa. Zaniká, keď na objekt danej triedy nie je žiadna referencia a spustí sa garbage collector. To čo sa používa v ne-OPP ako globálna premenná je úplne niečo iné ako premenná triedy.
Každopádne (k téme) var používam asi iba s LINQ, inicializácii WCF klientov a podobných veciach.
Stejně jsi nevěl, že VAR jako instanční použít nejde. Opravdu? (A pokud teda mluvis o instancnich promennych - muzes nam, co jsme do tveho prichodu nic nevedeli, jeste vysvetlit, proc ze se nemaji prilis pouzivat, jaks psals?
Chtěl bych se ještě jednou vrátit k VAR. Zde uvedu několik příkladů. Máme jednoduchou třídu. Příklad 1
namespace ClassLibrary1
{
public class Class1
{
private UserControl1 us = new UserControl1();
private object test1()
{
var x = us;
return x;
}
private object test2()
{
object x = us;
return x;
}
}
}
// Dissasebler těchto funkcí :
.method private hidebysig instance object
test1() cil managed
{
// Code size 14 (0xe)
.maxstack 1
.locals init ([0] object x,
[1] object CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld class ClassLibrary1.UserControl1 ClassLibrary1.Class1::us
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: stloc.1
IL_000a: br.s IL_000c
IL_000c: ldloc.1
IL_000d: ret
} // end of method Class1::test1
.method private hidebysig instance object
test2() cil managed
{
// Code size 14 (0xe)
.maxstack 1
.locals init ([0] object x,
[1] object CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld class ClassLibrary1.UserControl1 ClassLibrary1.Class1::us
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: stloc.1
IL_000a: br.s IL_000c
IL_000c: ldloc.1
IL_000d: ret
} // end of method Class1::test2
Příklad 2
public class Class1
{
private int test1()
{
var x = 100;
return x;
}
private int test2()
{
int x = 100;
return x;
}
}
// Dissasebler těchto funkcí :
.method private hidebysig instance int32
test1() cil managed
{
// Code size 10 (0xa)
.maxstack 1
.locals init ([0] int32 x,
[1] int32 CS$1$0000)
IL_0000: nop
IL_0001: ldc.i4.s 100
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: stloc.1
IL_0006: br.s IL_0008
IL_0008: ldloc.1
IL_0009: ret
} // end of method Class1::test1
.method private hidebysig instance int32
test2() cil managed
{
// Code size 10 (0xa)
.maxstack 1
.locals init ([0] int32 x,
[1] int32 CS$1$0000)
IL_0000: nop
IL_0001: ldc.i4.s 100
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: stloc.1
IL_0006: br.s IL_0008
IL_0008: ldloc.1
IL_0009: ret
} // end of method Class1::test2
Příklad 3 jak vznikají chyby :
public class Class1
{
private object test1()
{
var x = 100.0;
return x;
}
private object test2()
{
object x = 100;
return x;
}
}
// Dissasebler těchto funkcí :
.method private hidebysig instance object
test1() cil managed
{
// Code size 22 (0x16)
.maxstack 1
.locals init ([0] float64 x,
[1] object CS$1$0000)
IL_0000: nop
IL_0001: ldc.r8 100.
IL_000a: stloc.0
IL_000b: ldloc.0
IL_000c: box [mscorlib]System.Double
IL_0011: stloc.1
IL_0012: br.s IL_0014
IL_0014: ldloc.1
IL_0015: ret
} // end of method Class1::test1
.method private hidebysig instance object
test2() cil managed
{
// Code size 15 (0xf)
.maxstack 1
.locals init ([0] object x,
[1] object CS$1$0000)
IL_0000: nop
IL_0001: ldc.i4.s 100
IL_0003: box [mscorlib]System.Int32
IL_0008: stloc.0
IL_0009: ldloc.0
IL_000a: stloc.1
IL_000b: br.s IL_000d
IL_000d: ldloc.1
IL_000e: ret
} // end of method Class1::test2
Cílem bylo ukázat, že VAR nám nezrychlí náš kód, ale zavede nepřehlednost v programu a nepatří tam.
"Cílem bylo ukázat, že VAR nám nezrychlí náš kód, ale zavede nepřehlednost v programu a nepatří tam."
Proč by tam nepatřil? Když budeš mít nějakou kolekci a uvnitř další kolekci, tak je 3x rychlejší napsat var než to psát 2x. Používám ho i když je typ velmi zdlouhavý, nebo dost často, když zkouším nějaký krátký kód, který letí stejně za pár minut do pryč.
Nevim sice co si tim MSIL chtel dokazat, ale snad nikdo nikdy netvrdil ze var zrychluje kod.
Odpovím (paku i sadlomaslox25). Pánové, když odpovídáte čtěte
pozorně o čem se ve vláknu píše. Nikde není zmínka o větě "Zakazuji
používat VAR" a také nikde není zmínka o rychlosti.
Klidně VAR používej pokud ti nevadí nepřehlednost.
Co se týká MSIL dal jsem ukázku proto, že je pro každého i když se
neorientuje v MSIL je jasné ,že generovaný kód je stejný. Přece nejde o
rychlost.
Závěr :
Proč mám psát kód , který je hůře čitelný a nemá vliv na velikost ani
na rychlost ?
Protože se to rychleji píše?
Přehlednost tím netrpí, pokud to používáš rozumně.
Obvykle se to používá spíš na třídy a taky je potřeba používat
inteligentnější názvy tříd/metod/proměnných než třeba x,
pak je všechno jasné i s var.
Viz třeba:
Customer customer = customers.GetByName(name);
vs
var customer = customers.GetByName(name);
Protože se takový kód lépe čte a je přehlednější.
Ačkoliv sám také čtu knihy často odzadu, jedinou větu čtu jako evropan obvykle zleva doprava a nerad se vracím očima. Použití var usnadňuje čtení kódu, pokud je v kontextu možné snadno odvodit výsledný typ. Narozdíl od explicitní definice typu, implicitní definice takový způsob čtení umožňuje.
var dict = new Dictionary<int, string>();
var i = 1;
Čti:
"proměnná dict obsahuje instanci Dictionary<int, string> a je stejného
typu"
"proměnná i obsahuje hodnotu 1 a je typu integer"
Co je na tom nečitelného?
Jediný rozdíl mezi implicitním a explicitním zavedením typu spočívá v tom, že implicitně to za nás dělá kompilátor. A na tom není nic špatného. Typová inference je běžná věc a používáš ji častěji, než si sám uvědomuješ.
var a = new[] { 1, 2, 3 };
var b = a.First();
Na dvou řádkách kódu najdeš hned čtyři případy typové inference. Prvním je definice pole, kde kompilátor odvodí typ z jeho hodnot. Druhým je definice proměnné a, kde kompilátor odvodí typ int[] na základě implicitní hodnoty. Třetím je odvození typu funkce [int Fist<int>()], což také provede kompilátor. Čtvrtým je na základě návratové hodnoty implicitně typované funkce Fist<T> odvození typu proměnné b. A ačkoliv bys mohl napsat explicitně a.First<int>(), určitě to neděláš?
Takže otázka zní, proč tam var a nepatří, ale a.First() tam patří? Odpověď je, že tam patří, protože zjednoduší a zpřehlední kód. Problém s takovým kódem často mají programátoři uvázaní na C a podobné jazyky. Za posledních 20 let se programování hodně posunulo a jasně se ukazuje, že dynamismus v jazyku (a teď nemám na mysli přímo var, to je statický typ) zrychluje vývoj a usnadňuje práci.
klicove slovo var ma 2 duvody. prvni je ze umoznuje nahradit slozite nazvy typu slovem var. to se pouziva hlavne u linq pokud vracis objekty ktere jsou sezazene,zgroupovane,slovniky. druhy duvod je ze linq metoda projekce umoznuje vytvaret anonymni tridy, se kterymi nejde pracovat jinak nez bez var.
Důvodem byly anonymní typy - a to nejen anonymní třídy, ale také uzávěry, které byly velice užitečné s příchodem EntityFrameworku.
var osoby = dbContext.Osoba.
Where(o => o.jmeno == "tomas").
Select(o => new { Jmeno = o.jmeno, Prijmeni = o,prijmeni });
Přečti si můj předchozí příspěvek a zkus si spočítat, kolik případů typové inference je na tomhle jediném řádku. Pokud nemusíš na každém místě uvádět explicitní typ, kód se drasticky zkrátí a zjednoduší.
Já vám nevím, ale kdyby se zamýšlelo používat neustále VAR, proč pak vymysleli jiné typy ?
Protože var není typ, ale deklarace proměnné s typem implicitně odvozeným?
var není nový datový typ. Pročti si tu celý thread.
Dobře. Ale vysvětlete mi, proč psát např. var promenna = 1 a nenapsat rovnou int promenna = 1 ? Nezabírá deklarace proměnné s typem implicitně odvozeným náhodou více procesorového času při překladu ?
Pominu, že to je naprosto nesmyslný argument a nebudu se rozepisovat o složitosti fází kompilace v rámci jazyka a porovnání mezi jazyky. Budu předpokládat, že by takový argument dával smysl a zeptám se, proč by měla zabírat více času? Stačí se zamyslet nad tím, co musí kompilátor udělat:
int a = 1 -- vs -- var b = 1
Obě dvě možnosti musí provést kroky a-c, ale protože proměnná b nemá typ, dokud není známý typ pravé strany výrazu, odpadá krok (b) a typ proměnné se jednoduše uloží k proměnné.
Problém celé téhle diskuse je o tom, že někteří netuší, odkud a proč se v C# tyhle nové vymoženosti jako Tuples, LINQ nebo typová inference vzali. Ano, je to převzato z F# (konkrétně LINQ určitě), potažmo z funkcionálního programování.
Ve většině zdrojů, které jsem nedávno k C# četl, nemá nikdo problém
var používat. Jednoduše proto, že dvakrát opakovat totéž je čirý
masochismus.
Ale je na to hezké definice, opak DRY je WET, tomto pípadě Write Everything Twice:
http://cs.wikipedia.org/…eat_yourself
*
*DRY vs. WET
Chyby při používání principu DRY se často označují zkratkou WET neboli Write everything twice! (tj. „Piš vše dvakrát“), či We enjoy typing (tj. „Zbožňujeme psaní“).*
*
Zobrazeno 50 zpráv z 54.