Programim dhe zhvillim, javascript, python, php, html

Kur të përdoret: Tuple vs Class në C# 7.0

Përpara Tuples, unë krijoja një klasë dhe variablat e saj, pastaj krijoja objekt nga kjo klasë dhe e bëja atë objekt llojin e kthimit për disa funksione.

Tani, me tuples, unë mund të bëj të njëjtën gjë, dhe në C# 7.0 mund të caktojmë emra të kuptueshëm për pronat e tupleve (përpara kësaj, ishte item1, item2, etj.)

Pra, tani po pyes veten, kur mund të përdor tuple dhe kur të krijoj një klasë në C# 7.0?

20.06.2017

  • Vini re se emrat e elementeve tuple janë kryesisht një veti e kohës së projektimit dhe nuk ekzistojnë në IL të përpiluar. Pra, nëse ju intereson kjo, ju keni një arsye tjetër për klasat e duhura. 20.06.2017
  • @OrkhanAlikhanov Ndërsa ky do të ishte një objektiv i saktë dublikatë, unë pajtohem me OP që kohët kanë ndryshuar tani me C# 7, kështu që përgjigjet nga 2012 dhe 2010 zbatohen vetëm pjesërisht tani. 20.06.2017
  • @poke që nuk është një objektiv i vlefshëm dublikatë, ajo pyetje kishte të bënte me System.Tuple, ky ka të bëjë me System.ValueTuple i cili ka sheqer të veçantë sintaksor në C# 7. 20.06.2017
  • @Theraot E kuptoni që po kritikoja sugjerimin për ta mbyllur këtë pyetje, apo jo? Unë e di se për çfarë është kjo pyetje, prandaj sugjerova ta lija këtë të hapur. 20.06.2017
  • @Theraot Oh, sapo bëra të njëjtin gabim në interpretimin e kësaj pyetjeje si referencë ndaj System.Tuple, pasi thotë… Tuple. Nëse jeni të sigurt se në të vërtetë i referohet diçkaje tjetër, atëherë duhet ta modifikoni për ta bërë këtë më të qartë. E ktheva mbylljen time duke supozuar se keni të drejtë. 20.06.2017

Përgjigjet:


1

Meqenëse kjo përgjigje po shkakton një farë konfuzioni në mesin e disa njerëzve këtu, unë duhet të sqaroj se - sipas pyetjes - të gjitha referencat për "tuple" këtu i referohen tipit ValueTuple dhe tipareve të reja të sheqerit sintaksor tuple të C# 7 dhe në asnjë mënyrë nuk i referohen Llojet e vjetra System.Tuple të referencës.

Pra, tani po pyes veten, kur duhet të përdor tuples dhe kur duhet të krijoj një klasë në c# 7.0?

Vetëm ju mund t'i përgjigjeni vërtet kësaj pyetjeje pasi varet vërtet nga kodi juaj.

Megjithatë, ka udhëzime dhe rregulla që mund të ndiqni për t'ju udhëhequr në zgjedhjen midis tyre:

Tuplet janë vlera, kështu që kopjohen sipas vlerës, dhe jo sipas referencës.

Në shumicën e rasteve, kjo nuk duhet të jetë një problem. Megjithatë, nëse po kaloni rreth tufave të strukturave të mëdha, kjo mund të ketë një ndikim në performancën. Megjithatë, vendorët/kthimet e referencës mund të përdoren për të zgjidhur këto çështje të performancës.

Për më tepër, për shkak se ato janë vlera, modifikimi i një kopjeje nga distanca nuk do të ndryshojë kopjen origjinale. Kjo është një gjë e mirë, por mund të tërheqë disa njerëz.

Emrat e elementeve të dyfishta nuk vazhdojnë

Emrat e dhënë elementeve përdoren nga përpiluesi dhe (në shumicën e rasteve) nuk janë të disponueshëm në kohën e ekzekutimit. Kjo do të thotë se reflektimi nuk mund të përdoret për të zbuluar emrat e tyre; ato nuk mund të aksesohen në mënyrë dinamike dhe ato nuk mund të përdoren në pamjet me brisk.

Gjithashtu kjo është një konsideratë e rëndësishme me API-të. Një tuple e kthyer nga një metodë është përjashtim nga rregulli në lidhje me zbulueshmërinë e emrit pas përpilimit. Përpiluesi i shton metodës atribute që mbajnë informacione për emrat e tuples. Kjo do të thotë që ju mund të ktheni në mënyrë të sigurt një tuple nga një metodë publike në një asamble dhe të përdorni emrat e saj në një tjetër.

Tufat janë të lehta

Tuplet janë shumë më të thjeshtë për t'u shkruar sesa tipat, pasi ato janë më pak të folura dhe deklarata mund të "inlinohet" (dmth. deklarohet në pikën e përdorimit). Kjo funksionon mirë kur deklaron një metodë që kthen vlera të shumta, për shembull.

Megjithatë, për shkak se ato janë deklaruar në pikën e përdorimit, nëse keni MethodA që thërret MethodB që thërret MethodC dhe secili kthen një tuple, do t'ju duhet të ripërcaktoni tuplenë në çdo fazë. Nuk ka (ende) një mënyrë për të krijuar një pseudonim të një tupleje dhe ri- duke e përdorur atë nëpër metoda të shumta.

Thjesht përdorni sensin e përbashkët

Për çdo situatë ku mund të mendoni të përdorni një tuple: thjesht bëni vetes pyetjen: "a do ta thjeshtojë një tuple kodin këtu". Nëse përgjigja është "po", atëherë përdorni një. Dhe kjo në fund të fundit është konsiderata kryesore nëse duhet përdorur një tuple apo një klasë me porosi.

20.06.2017
  • ValueTuple është lloji i vlerës. Tupleështë lloj referimi. Aq e thjeshtë Tuple nuk do të kopjohet me referencë. Duhet ta përmendni me shkronja të zeza sepse është konfuze tani 20.06.2017
  • @Szer, pyetja ka të bëjë me tuplet e C# 7, kështu që nuk e kuptoj pse ka ndonjë konfuzion. Por e kam përditësuar pyetjen për të sqaruar këtë pikë. 20.06.2017
  • @DavidArno kur fillova të përdor C#7 për herë të parë nuk e kisha të qartë nëse sintaksa e re Tuple ishte një lloj i ri apo thjesht mbështetje gjuhësore. 22.06.2017
  • Jam i befasuar që emrat e elementeve të dyfishta nuk mund të përdoren në pamjet Razor. A nuk konvertohen skedarët Razor në C# dhe më pas përpilohen? Nëse po, ata duhet të shohin emrat e elementeve të dyfishta nga metadata/IL, ashtu si çdo përmbledhje klienti. 03.07.2017
  • @JulienCouvreur, me sa di unë, është një kufizim i veglave të rrojes. Megjithatë, nga pamja e github.com/aspnet/Razor/issues/1046, kjo tani ose është rregulluar ose një rregullim do të dalë së shpejti. 03.07.2017
  • Faleminderit për lidhjen. Duket sikur nuk ishte e nevojshme asnjë rregullim (ata sapo tërhoqën një paketë të re nuget). Unë do të vazhdoj me ekipin ASP.NET Core për të kuptuar dhe qetësuar historinë e adoptimit të përpiluesit. Gëzuar 05.07.2017
  • Unë do të thosha se tuplet kanë kuptim, për sa i përket cilësisë, brenda një sfere të kufizuar. Like Nëse përdorni një metodë që kthen një tuple nga një klasë tjetër, ndoshta duhet të konsideroni përdorimin e një klase në vend të kësaj, duke shmangur kompleksitetin shtesë. Një klasë DTO do të ketë një emër kuptimplotë për të identifikuar atë që po kthehet. 17.04.2018
  • Pika juaj e fundit është e mirë për çdo veçori gjuhësore. Unë ndonjëherë shkruaj kodin në mënyra të ndryshme dhe krahasoj atë që duket më e lehtë për t'u lexuar. 22.05.2018
  • Ju mund të përdorni një metodë delegate për alias një metodë që kthen një tuple për të lejuar rifaktorim më të lehtë. 30.10.2018

  • 2

    Në përgjithësi, klasat e emëruara kanë njëfarë rëndësie në hartimin e sistemit tuaj. Ata janë gjithashtu më të folur për të shkruar. Për shembull, mund të keni një klasë të quajtur MediaFileOpener. Është e rëndësishme për dizajnin që ne të dimë se çfarë bën kjo klasë - ne jemi duke punuar me skedarë media!

    Llojet anonime dhe tuples përdoren kur nuk ka rëndësi dizajni dhe gjithçka që dëshironi është një Objekt i Transferimit të të Dhënave (DTO) i lehtë për të lëvizur informacionin.

    Si rregull, nëse klasa juaj kërkon ndonjë dokumentacion për të përshkruar se për çfarë shërben, ose nëse ka sjellje që ofron, përdorni një klasë të plotë. Nëse gjithçka që ju nevojitet është ruajtja e përkohshme ose një lloj grupimi, përdorni një Tuple. Konsideroni një situatë ku dëshironi të ktheni më shumë se një vlerë nga një metodë asinkronike. Tuple është krijuar për të zgjidhur këtë problem.

    20.06.2017

    3

    Përdor një klasë

    Nëse objektet tuaja janë entitete që përdoren gjerësisht në të gjithë aplikacionin tuaj dhe ruhen gjithashtu në një lloj ruajtjeje të vazhdueshme si një bazë të dhënash relacionale (SQL Server, MySQL, SQLite), një bazë të dhënash NoSQL ose cache (Redis, Azure DocumentDB) ose edhe në të thjeshta skedarë teksti ose CSV.

    Pra, po, çdo gjë këmbëngulëse duhet të ketë klasën e vet.

    Përdor një Tuple

    Nëse objektet tuaja janë jetëshkurtër pa një kuptim të veçantë për aplikimin tuaj. Për shembull, nëse duhet të ktheni shpejt një palë koordinata, është më mirë të keni diçka të tillë:

    (double Latitude, double Longitude) getCoordinates()
    {
        return (144.93525, -98.356346);
    }
    

    se sa të përcaktojë një klasë të veçantë

    class Coordinates
    {
        public double Latitude { get; set; }
        public double Longitude { get; set; }
    }
    

    Një Tuple do t'ju kursejë kohë nga nevoja për të shpërndarë memorie në grumbull duke përdorur new për një operacion kaq të thjeshtë.

    Një herë tjetër kur më duken të dobishme tuples është kur kryejmë operacione të shumta matematikore në disa operandë

    (double Result1, double Result2, double Result3) performCalculations(int operand1, int operand 2)
    

    Nuk ka kuptim të përcaktohet një klasë në këtë rast. Pavarësisht se çfarë janë llogaritjet, rezultatet nuk i përkasin një klase. Pra alternativa do të ishte përdorimi i variablave out, por besoj se tuplet janë më shprehës dhe rezultojnë në përmirësim të lexueshmërisë.

    20.06.2017
  • Unë do ta përcaktoja Coordinates si struct në vend të class. 20.06.2017
  • Koordinatat do të ishin një shembull i mirë për të mos përdorur një tuple pasi është një gjë mjaft e zakonshme që ka të ngjarë të keni nevojë gjatë gjithë kohës. Përveç kësaj, mund të mbingarkoni ToString për të siguruar një dalje të lexueshme (rastësisht, ToString i parazgjedhur i tuple-s tashmë funksionon mirë këtu) dhe mbingarkoni Equals/GetHashCode për krahasime të barazisë gjithashtu. 20.06.2017
  • IMHO, kjo duket si një përgjigje shumë e mendimit, me një udhëzues të paqartë për dizajn. Unë nuk mendoj se oop ka të bëjë me këtë (klasat anonime mund të vendosen në të dyja kategoritë tuaja). Gjithashtu, shtimi i qëndrueshmërisë së nivelit të bazës së të dhënave nuk ka të bëjë fare me këto konsiderata. 02.01.2020

  • 4

    Në përgjithësi ju dëshironi të keni një klasë kur objekti juaj do të përdoret diku tjetër ose nëse ai përfaqëson një objekt real ose një koncept në domenin tuaj. Ju ndoshta do të krijoni një klasë për të përfaqësuar një makinë ose një dyqan makinash, jo tuples.

    Nga ana tjetër, ndonjëherë ju thjesht dëshironi të ktheni disa objekte nga një metodë. Ndoshta nuk përfaqësojnë asgjë të veçantë, thjesht duhet t'i ktheni ato së bashku në atë metodë të veçantë. Ndonjëherë, edhe nëse ato përfaqësojnë një koncept nga domeni juaj (të themi se po ktheni (Car, Store), i cili mund të përfaqësohet si një objekt Sale), në fakt nuk do t'i përdorni ato askund -- thjesht po lëvizni të dhëna. Në ato raste, është mirë të përdorni tufa.

    Tani, duke folur në mënyrë specifike për C#, ka edhe një gjë që duhet të dini. Lloji tuple i C# 7 është në fakt ValueTuple, që është një strukturë. Ndryshe nga klasat, të cilat janë tipe referimi, strukturat janë tipe vlerash. Mund të lexoni më shumë rreth kësaj në msdn. Më e rëndësishmja, dijeni se ato mund të përfshijnë shumë kopjime, ndaj kini kujdes.

    20.06.2017

    5

    Unë mendoj se kjo do të bëhet një pyetje që bëhet shumë. Aktualisht nuk ka asnjë "praktikë më të mirë" se kur duhet të përdoren tuplet e vlerave të reja kundrejt një klase.

    Megjithatë, ia vlen të lexoni çfarë doli gjatë bisedave të mëparshme rreth versioneve të mëparshme të tuples vs një class.

    Sipas mendimit tim, tupleja e vlerës duhet të përdoret vetëm minimalisht dhe me jo më shumë se një maksimum prej tre vlerash. Mendoj se kjo vendos një ekuilibër të mirë të "kthimit të disa vlerave pa nevojën e një klase" dhe "rrëmujës së tmerrshme të vlerave". Nëse keni më shumë se tre vlera për të kthyer, bëni një klasë.

    Unë gjithashtu nuk do të përdorja kurrë një tuple për t'u kthyer nga një API me përballje publike që konsumatorët do të duhet të përdorin. Përsëri, thjesht përdorni një klasë.

    Këtu është një kod i botës reale që kam përdorur:

    public async Task<(double temperature, double humidity, string description)> DownloadTodaysForecast()
    

    Sapo dua të kthej të dhëna më komplekse, bëj një klasë.

    20.06.2017

    6

    Dua të filloj duke përmendur se C# tashmë kishte mbështetje për lloje anonime. Cilat janë llojet e referencës. Kështu, ju tashmë kishit një alternativë të përshtatshme për të krijuar një klasë të emërtuar.

    Një avantazh i një klase të emërtuar është se do të jetë më e lehtë për t'u ripërdorur (për shembull nëse ju nevojitet i njëjti lloj në shumë vende) dhe dokumentimi. Meqenëse lloji anonim është anonim, ju mund të merrni variabla të shtypura në të vetëm nëse mund të përdorni var, e cila kufizon kontekstet në të cilat llojet anonime janë të dobishme (për shembull, nuk mund t'i përdorni ato si lloje fushash, lloje kthimi ose lloje parametrash ).

    Sigurisht, ju mund të kaloni disa nga kufizimet e llojeve anonime duke përdorur System.Tuple. I cili është gjithashtu një lloj referimi, dhe ju mund ta përdorni atë në mënyrë eksplicite. E keqja është se i mungojnë emrat e personalizuar për anëtarët.


    C# 7 tuples (ValueTuple ) mund të konsiderohet i ngjashëm me llojet anonime. Dallimi i parë është se ato janë lloje vlerash. Kjo do të thotë që këta tuple do të kenë avantazhe të performancës për sa kohë që qëndrojnë në shtrirjen lokale ose janë duke lëvizur nëpër pirg (që është përdorimi i zakonshëm i llojeve anonime, për shkak të kufizimit të tij).

    Dallimi i dytë është se sintaksa e re lejon tuples të shfaqen në më shumë vende sesa lloje anonime, siç e dini, ju keni sheqer sintaksor për të përcaktuar llojin e kthimit në ValueTuple (ndërsa përdorni lloje anonime ju duhej të kthenit object).

    Dallimi i tretë është se ValueTuple mbështet dekonstruksionin jashtë kutisë. Për të cituar Çfarë ka të re në C# 7.0:

    Një mënyrë tjetër për të konsumuar tuple është zbërthimi i tyre. Një deklaratë dekonstruktive është një sintaksë për ndarjen e një tuple (ose vlerë tjetër) në pjesët e saj dhe caktimin e atyre pjesëve individualisht në variabla të freskëta:

    (string first, string middle, string last) = LookupName(id1); // deconstructing declaration
    WriteLine($"found {first} {last}.");
    

    Gjë që mund ta bëni edhe me llojet e personalizuara duke shtuar një metodë e dekonstruktimit.


    Për abstrakt:

    • ValueTuple ka sheqer sintaksor në C# 7.0, i cili duhet të merret parasysh për lexueshmëri.
    • ValueTuple është një lloj vlere. Zbatohen të gjitha të mirat dhe të këqijat midis përdorimit të një class dhe një struct.
    • ValueTuple mund të përdoret në mënyrë eksplicite (me ose pa sheqer sintaksor) duke e lejuar atë të ketë shkathtësinë e System.Tuple duke ruajtur anëtarët e emëruar.
    • ValueTuple mbështet dekonstruksionin.

    Duke pasur parasysh se duhet të jetë sheqer sintaksor, unë do të thosha se argumenti më i fortë për të zgjedhur ValueTuple është i njëjti argument për të zgjedhur një struct. E cila do të ishte ideale për lloje të vogla, të pandryshueshme, që jetojnë kryesisht në pirg (kështu që nuk keni shumë boks dhe çboks).

    Duke krahasuar ValueTuple me një strukturë të plotë, duke marrë parasysh sheqerin sintaksor, unë do të sugjeroja të përdorni ValueTuple si parazgjedhje, përveç nëse keni nevojë për një paraqitje eksplicite ose duhet të shtoni metoda në të.

    Dua të them gjithashtu se sheqeri sintaksor nuk përmirëson domosdoshmërisht lexueshmërinë. Arsyeja kryesore është se ju nuk po e emërtoni llojin dhe emri i llojit i jep kuptim kodit. Përveç kësaj, ju mund të shtoni dokumentacion në një deklaratë struct ose class që lehtëson të kuptuarit.

    Në përgjithësi, situata ku ValueTuple shkëlqen vërtet po kthen vlera të shumta nga një metodë. Në këtë rast heqja e nevojës për krijimin e parametrave të rinj out. Dhe dokumentacioni i ValueTuple i përdorur mund të jetojë në dokumentacionin e metodës. Nëse gjeni se duhet të bëni diçka tjetër me ValueTuple (për shembull, duke përcaktuar metodat e zgjerimit), unë do të sugjeroja të konsideroni krijimin e një lloji të emërtuar në vend të kësaj.

    20.06.2017

    7

    Unë do të shmang përdorimin e tuples si një lloj kthimi të metodave publike. Në raste të tilla unë do të preferoja të përcaktoja një klasë ose strukturë.

    23.01.2018
  • A mund të shpjegoni pse? 11.10.2019
  • @Fütemire Google i mungon abstraksioni ose aroma primitive e dizajnit të obsesionit. 20.11.2020
  • @MilosMrdovic faleminderit, do ta shqyrtoj. 04.12.2020
  • Marrëveshje e fortë. Tuplet e emërtuar ofrojnë një përkufizim të dobët të domenit për ndërfaqen publike të bibliotekës suaj. Unë supozoj se është mirë nëse i fshehni ato në të brendshmet tuaja për një skenar të vetëm, por çdo gjë e ekspozuar publikisht, sipas definicionit, pritet të përdoret. Përcaktoni një abstraksion të përshtatshëm për domenin! 25.05.2021

  • 8

    Tuples kanë për qëllim të përfaqësojnë vlera të shumta, si kur një metodë synon të kthejë vlera të shumta. Mbështetja tuple në C# 7 përdor System.ValueTuple<...> raste për të përfaqësuar atë grup vlerash. Emrat e atyre vlerave janë të vlefshme vetëm në kontekstin ku ato përdoren dhe nuk zbatohen.

    Klasat synojnë të përfaqësojnë një vlerë të vetme me disa atribute.

    20.06.2017

    9

    Tuple është një opsion i shkëlqyeshëm kur dëshironi të kombinoni vlera të shumta (mund të jenë lloje të ndryshme) në një objekt pa krijuar një klasë të personalizuar. Në këtë rast, Tuple do të ishte një opsion i shpejtë dhe i përsosur.

    15.03.2018

    10

    Kohët e fundit kam krahasuar ndryshimin e performancës për një rast që kisha përfshirë ose një tuple që përmban 2 (ose 4) primitivë dhe një klasë që përmban 2 (ose 4) të të njëjtave lloje primitive. Po ndaj këtu në rast se mund të ndihmojë dikë.

    Profilimi

    26.03.2021
  • Cili ishte rezultati? 14.07.2021
  • @GrahamLaight Sipas pamjes së ekranit, përdorimi i një Tuple‹T1, T2, TN› është dukshëm më i shpejtë sesa përdorimi i një klase me të njëjtin grup llojesh fushash, si për inicializimin ashtu edhe për aksesin në terren. Për më tepër, sa më i madh të jetë numri i fushave, aq më i madh është ndryshimi. 15.07.2021

  • 11

    Për një pjesë të shpejtë të kodit që do të përdoret vetëm një herë, përdorni tuples. Nëse kodi do të duhet të ruhet, përdorni klasat. Është demoralizuese të shikosh kodin dhe të shohësh shprehje si:

    if (t.Item4 == x.Item3)
    
    14.07.2021
    Materiale të reja

    Masterclass Coroutines: Kapitulli-3: Anulimi i korutinave dhe trajtimi i përjashtimeve.
    Mirë se vini në udhëzuesin gjithëpërfshirës mbi Kotlin Coroutines! Në këtë seri artikujsh, unë do t'ju çoj në një udhëtim magjepsës, duke filluar nga bazat dhe gradualisht duke u thelluar në..

    Faketojeni derisa ta arrini me të dhënat false
    A e gjeni ndonjëherë veten duke ndërtuar një aplikacion të ri dhe keni nevojë për të dhëna testimi që duken dhe duken më realiste ose një grup i madh të dhënash për performancën e ngarkesës...

    Si të përdorni kërkesën API në Python
    Kërkesë API në GitHub për të marrë depot e përdoruesve duke përdorur Python. Në këtë artikull, unë shpjegoj procesin hap pas hapi për të trajtuar një kërkesë API për të marrë të dhëna nga..

    Një udhëzues hap pas hapi për të zotëruar React
    Në këtë artikull, do të mësoni se si të krijoni aplikacionin React, do të mësoni se si funksionon React dhe konceptet thelbësore që duhet të dini për të ndërtuar aplikacione React. Learning..

    AI dhe Psikologjia — Pjesa 2
    Në pjesën 2 të serisë sonë të AI dhe Psikologji ne diskutojmë se si makineritë mbledhin dhe përpunojnë të dhëna për të mësuar emocione dhe ndjenja të ndryshme në mendjen e njeriut, duke ndihmuar..

    Esencialet e punës ditore të kodit tim VS
    Shtesat e mia të preferuara - Git Graph 💹 Kjo shtesë është vërtet e mahnitshme, e përdor përpara se të filloj të punoj për të kontrolluar dy herë ndryshimet dhe degët më të fundit, mund të..

    Pse Python? Zbulimi i fuqisë së gjithanshme të një gjiganti programues
    Në peizazhin gjithnjë në zhvillim të gjuhëve të programimit, Python është shfaqur si një forcë dominuese. Rritja e tij meteorike nuk është rastësi. Joshja e Python qëndron në thjeshtësinë,..