C# Dynamisches Klassenarray

OP (Firma: HEGRO GmbH) #4569684
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
OP (Firma: HEGRO GmbH) #4569741
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?
Gast #4569774
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.
Gast #4569785
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.
Gast #4569810
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren