Forum: PC-Programmierung C# Dynamisches Klassenarray


von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Hallo ihr,

ich steh grad wieder total auf dem Schlauch. Ich möchte in einer Klasse 
eine weitere Klasse dynamisch in einem Array initialisieren, kriege es 
aber nicht hin. Ich bekomme eine null-reference exception:

1
public class ProjectData
2
{
3
    public ProjectData()
4
    {
5
        runs = 0;
6
    }
7
8
    public void Add(ref RunData data)
9
    {
10
        Run[runs] = new RunData(); // hier die null-reference exception
11
        Run[runs] = data;
12
        runs++;
13
    }
14
15
    private runs;
16
    public RunData[] Run;
17
}
18
19
public class RunData
20
{
21
    public RunData()
22
    {
23
    }
24
}

Ich habe gelesen, dass es mit etwas ähnlichem wie "List" geht, würde 
diesen Weg aber ungern einschlagen, falls ich es "klassisch" lösen kann.

Vielen Dank schonmal für eure Hilfe!
Grüße
Reggie

: Bearbeitet durch User
von ich (Gast)


Lesenswert?

Ich kann zwar kein C#. Wenn  ich jedoch "c# new array" bei gurgel 
eingebe, sieht das igendwie immer anders aus, als bei dir ;)

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Ja, das "public RunData[] Run;" und "Run[runs] = new RunData();" ist 
natürlich Schwachsinn meinerseits.

Ich benötige etwas in Richtung Array.Resize() nur eben für 
Klassenarrays.

... gerade ausprobiert. Mit Array.Resize() klappts. Danke für den Stups 
:)

von TriHexagon (Gast)


Lesenswert?

Wie oft wird dem Array etwas angehängt? array.Resize() ist 
performancemäßig nicht so der Hit. Dann schon lieber eine verkettete 
Liste mit List<RunData>.

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

TriHexagon schrieb:
> Wie oft wird dem Array etwas angehängt?
Ist in dem Fall absolut nicht zeitkritisch.

TriHexagon schrieb:
> array.Resize() ist
> performancemäßig nicht so der Hit. Dann schon lieber eine verkettete
> Liste mit List<RunData>.
Danke für den Tipp, ich werde es mir für die Zukunft im Hinterkopf 
behalten! Eine "klassische" Möglichkeit gibt es allerdings nicht oder?

von TriHexagon (Gast)


Lesenswert?

Ich wüsste nicht was in diesem Fall klassischer ist als List<> ;)
Ein normales Array ist in C# eigentlich nicht darauf ausgelegt zu 
wachsen, obwohl es natürlich geht.

Alles zu List<>
https://msdn.microsoft.com/de-de/library/6sh2ey19(v=vs.110).aspx

Das sieht dann so aus:
1
var list = new List<RunData>();
2
list.add(new RunData());

von Zustimmer (Gast)


Lesenswert?

Ja, nimm List<T>. Das ist übrigens keine verkettete Liste, sondern quasi 
ein Array-Wrapper (Zugriff über Index möglich).

Reginald L. schrieb:
> public class ProjectData
> {
>     public ProjectData()
>     {
>         runs = 0;
>     }
>
>     private runs;

Da fehlt der Typ bei runs (und in diesem Kontext wird runs sowieso auf 0 
gesetzt, wenn es sich um einen eingebauten numerischen Wertetypen 
handelt; das musst du nicht explizit machen).

Reginald L. schrieb:
> Danke für den Tipp, ich werde es mir für die Zukunft im Hinterkopf
> behalten! Eine "klassische" Möglichkeit gibt es allerdings nicht oder?

Keine Ahnung was genau du mit "klassisch" meinst, aber List in C# 
würde ich schon so bezeichnen (wie TriHexagon). Das dürfte wohl die am 
häufigsten verwendete Collection sein. Arrays verwendet man aktiv 
praktisch nur, wenn es um "Low-Level-Sachen" geht und man genaue 
Kontrolle über das Resizing etc. benötigt und/oder es schneller als 
schnell sein muss (aber selbst dann schreibt man meist einen Wrapper). 
Also mehr oder weniger analog zu Arrays und std::vector in C++.

Reginald L. schrieb:
>> Wie oft wird dem Array etwas angehängt?
> Ist in dem Fall absolut nicht zeitkritisch.

Selbst wenn es so wäre, sollte man erst testen, denn auf modernen 
Prozessoren sind verkette Listen selbst bei relativ vielen Elementen und 
trotz der wegfallenden Kopiervorgänge und Allokationen entgegen der 
häufig ersten Vermutung oft langsamer.

von Zustimmer (Gast)


Lesenswert?

Zustimmer schrieb:
> trotz der wegfallenden [...] Allokationen

Nachtrag:
Ich meine damit die Größe der angeforderten Speicherblöcke. Die 
Allokationsfrequenz ist bei verketteten Listen natürlich meist deutlich 
höher, da für jedes Element einzeln Speicher reserviert werden muss, 
während bei Array-Wrappern fast immer "vorausgedacht" wird. Aber wenn es 
um Effizienz geht, muss man sowieso testen, da ja die Häufigkeit der 
jeweiligen Operationen (Zugriff, Hinzufügen, Entfernen, ...), die 
Auswirkungen des CPU-Caches etc. eine große Rolle spielen.
Ich füge das nur hinzu, weil ich mich oben ein wenig missverständlich 
ausgedrückt hatte.

von TriHexagon (Gast)


Lesenswert?

Zustimmer schrieb:
> Nachtrag:
> Ich meine damit die Größe der angeforderten Speicherblöcke. Die
> Allokationsfrequenz ist bei verketteten Listen natürlich meist deutlich
> höher, da für jedes Element einzeln Speicher reserviert werden muss,
> während bei Array-Wrappern fast immer "vorausgedacht" wird.

Bei C++ würde ich dir sofort zustimmen. Bei C# bin ich mir da gar nicht 
sicher wie das umgesetzt wird, immerhin wird bei jeder neuen Instanz von 
RunData (Referenztyp) sowieso neuer neuer Speicher vom Heap angefordert, 
allerdings muss auch noch der Zeiger auf das nächste Element irgendwo 
hin, also noch mal Speicher anfordern und dort zwei Zeiger ablegen 
(current, next)? Und ist das normale Array ein Vektor aus Zeigern die 
auf die Elemente zeigen? Hab mich mit C# schon länger nicht mehr 
beschäftigt...

Ansonsten ja, pauschal stimmts natürlich nicht ganz, kommt auf den 
Anwendungsfall an.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.