C# - Inkrementera variable varje gång .Add() körs på lista

Permalänk
Medlem

C# - Inkrementera variable varje gång .Add() körs på lista

Jag har en variabel som alltid ska vara lika med summan av alla talen i en List. Hur gör jag så att varje gång .Add() metoden körs på listan så ska variabeln ökas med det värde som variabeln som lades till i listan har (listan innehåller integers)?

Jag vill automatisera det och inte öka variabeln manuellt varje gång .Add() körs.

Permalänk
Hedersmedlem

Kan du inte bara modifiera listan via andra funktioner (som dessutom håller reda på summan och liknande)?

Permalänk
Medlem
Skrivet av Elgot:

Kan du inte bara modifiera listan via andra funktioner (som dessutom håller reda på summan och liknande)?

Låter som en bra idé.

Permalänk
Medlem

Jag är lite av en nybörjare när det gäller c# men har mer erfarenhet i c++ och jag tänkte mig något åt det här hållet:
(Har som sagt inte så bra koll på c# så jag kanske tänkt/skrivit fel)

public class IntList : List<int> { private int sum; public IntList() : base() { sum = 0; } public IntList(IEnumerable<int> collection) : base(collection) { sum = 0; foreach (int number in collection) { sum += number; } } public IntList(int capacity) : base(capacity) { sum = 0; } public override void Add(int number) { base.Add(number); sum += number; } public int Sum { get { return sum; } } }

Permalänk
Medlem
Skrivet av Murloc:

Jag har en variabel som alltid ska vara lika med summan av alla talen i en List. Hur gör jag så att varje gång .Add() metoden körs på listan så ska variabeln ökas med samma mängd som lades till listan (listan innehåller integers)?

Jag vill automatisera det och inte öka variabeln manuellt varje gång .Add() körs.

Eller så extendar du din List som

class SumTrackingList : List<int> { public Sum { get { return this.Sum(); } } }

Edit: Vilket naturligtvis är helt meningslöst eftersom det redan finns en Sum på IEnumerable, duh.
Skyller på lång arbetsdag

Problemet med att extenda List och overrida Add är att man även måste overrida Remove, RemoveAt, RemoveAll, GetEnumerator osv för att summan garanterat alltid ska vara korrekt.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem

Någon anledning till att du inte vill använda list.Count ?:P

Visa signatur

Spelrigg: 800D| i7 3930K@4,7 GHz - Custom WC | 32 GB Kingston HyperX Beast | 7970 GHz X-Edition |1x30 Dell U3011, 2x27" | Sennheiser HD650 | Xonar Essence STX |
Laptop: G74SX 17,3" 120 Hz 3D |
Server: Phenom II X4 955BE | Corsair XMS3 8 GB | 16 HDDs, 27 TB |
HTPCs: ASUS EEE Box 1.8 Ghz | Blu-Ray | OCZ Vertex 2 60 GB | 4 GB RAM |

Permalänk
Medlem

Tänkte vara med och leka och då bidra med något som inte redan nämns.

public class SumCollection : ObservableCollection<int> { public int Sum { get; private set; } protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { CalculateSum(); base.OnCollectionChanged(e); } private void CalculateSum() { Sum = this.Sum(); } }

Lite mer generisk:

public class SumCollection<T> : ObservableCollection<T> { public T Sum { get; private set; } protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { CalculateSum(); base.OnCollectionChanged(e); } private void CalculateSum() { if (this.Count == 0) { Sum = default(T); return; } dynamic dynamicSum = this[0]; for (int i = 1; i < this.Count; i++) { dynamicSum += this[i]; } Sum = dynamicSum; } }

Visa signatur

CPU: i7 6700k + Fractal Design S24 GPU: ASUS GeForce GTX 1070 8GB DUAL OC RAM: Kingston 16GB 2133MHz CL13 MB: MSI GAMING M7 PSU: EVGA Supernova G2 850W, 80+ Gold SSD: Samsung SM951 256GB M.2 NVMe + Samsung EVO 850 250GB M.2 Chassi: Fractal Design S Skrämar: Acer XB270HU + 2x Dell U2412M
NAS: Synology DS415+ (4x WD RED 6 TB) Console: Xbox One

Permalänk
Medlem
Skrivet av Teknocide:
Skrivet av Tino:

Tack för kommentarer och bättre lösning, som sagt nybörjare än så länge. Så då lärde man sig något nyttigt idag också

Permalänk
Avstängd

Undvik dynamic, den är slö och anses ofta som bad practice, den kan med fördel användas från Enhetstester etc, men undvik i produktionskod. Man kan även använa den istället för reflection där det behövs

edit: Och den tar bort tanken bakom generiska klasser

Visa signatur
Permalänk
Medlem
Skrivet av CyberVillain:

Undvik dynamic, den är slö och anses ofta som bad practice, den kan med fördel användas från Enhetstester etc, men undvik i produktionskod. Man kan även använa den istället för reflection där det behövs

edit: Och den tar bort tanken bakom generiska klasser

I min kod skulle dock kunna klassas som ett fall där det behövs. Alternativet hade varit att hantera 10 olika sätt att overloada Sum. Dock hanterar detta inte alla fall.

Visa signatur

CPU: i7 6700k + Fractal Design S24 GPU: ASUS GeForce GTX 1070 8GB DUAL OC RAM: Kingston 16GB 2133MHz CL13 MB: MSI GAMING M7 PSU: EVGA Supernova G2 850W, 80+ Gold SSD: Samsung SM951 256GB M.2 NVMe + Samsung EVO 850 250GB M.2 Chassi: Fractal Design S Skrämar: Acer XB270HU + 2x Dell U2412M
NAS: Synology DS415+ (4x WD RED 6 TB) Console: Xbox One

Permalänk
Avstängd
Skrivet av Tino:

I min kod skulle dock kunna klassas som ett fall där det behövs. Alternativet hade varit att hantera 10 olika sätt att overloada Sum. Dock hanterar detta inte alla fall.

problemet är att du inte längre är generisk, denna rad kan crashar vid runtime om du valt fel T
dynamicSum += this[i];

Jag skulle iallafall sätta nån form av contranst på genericen så att det inte kan runtime crasha, det hade varit nice om det fanns en contraint för operatorer typ

where T : Operator+

Alla värdetyper inkl iof även guid (som inte går att addera) implementerar IConvertable, den skulle iallafall minimera runtime crasher om du sätter den som constraint

Visa signatur
Permalänk
Medlem
Skrivet av CyberVillain:

problemet är att du inte längre är generisk, denna rad kan crashar vid runtime om du valt fel T
dynamicSum += this[i];

Jag skulle iallafall sätta nån form av contranst på genericen så att det inte kan runtime crasha, det hade varit nice om det fanns en contraint för operatorer typ

where T : Operator+

Alla värdetyper inkl iof även guid (som inte går att addera) implementerar IConvertable, den skulle iallafall minimera runtime crasher om du sätter den som constraint

Detta löser ju dock inte problemet, om du har en egen klass som implementerar + operatorn. Sen ser jag inte det som direkt farligt att den carshar runtime, för detta är runtime i utvecklingsmiljön och tester skall se till att detta aldrig sker i produktion.

Närmsta man kan komma är att skapa ett eget interface i still med IAddOperator som är tomt, och sedan kräva att de som använder sig av min kod, implementerar IAddOperator.

Visa signatur

CPU: i7 6700k + Fractal Design S24 GPU: ASUS GeForce GTX 1070 8GB DUAL OC RAM: Kingston 16GB 2133MHz CL13 MB: MSI GAMING M7 PSU: EVGA Supernova G2 850W, 80+ Gold SSD: Samsung SM951 256GB M.2 NVMe + Samsung EVO 850 250GB M.2 Chassi: Fractal Design S Skrämar: Acer XB270HU + 2x Dell U2412M
NAS: Synology DS415+ (4x WD RED 6 TB) Console: Xbox One