2010-03-16 1 views
6

Diciamo ipoteticamente (leggi: non penso di aver effettivamente bisogno di questo, ma sono curioso quando l'idea mi è saltata in testa), uno voleva una matrice di memoria messa da parte localmente nello stack, non sul mucchio. Per esempio, qualcosa del genere:Gli array basati su stack sono possibili in C#?

private void someFunction() 
{ 
    int[20] stackArray; //C style; I know the size and it's set in stone 
} 

Sto indovinando la risposta è no. Tutto quello che sono riuscito a trovare sono array basati su heap. Se qualcuno avesse bisogno di questo, ci sarebbero dei workaround? C'è un modo per mettere da parte una certa quantità di memoria sequenziale in un modo di tipo "valore"? Oppure le strutture con parametri denominati sono l'unico modo (come il modo in cui lo Matrix struct in XNA ha 16 parametri con nome (M11-M44))?

risposta

4

Quello che vuoi è stackalloc; sfortunatamente, è possibile utilizzarlo solo in un codice non sicuro, il che significa che non verrà eseguito in un contesto di autorizzazioni limitato.

Si potrebbe anche creare una struttura con il necessario numero di variabili in esso per ogni tipo di elemento, ma si avrebbe bisogno di un nuovo tipo per ogni dimensione di 'allineamento' si voleva utilizzare

+0

Hm, che dire di una LinkList primitiva? Nella struct set precedente/next struct dello stesso tipo ... non si ottiene la semantica ICollection, ma potrebbe essere sufficiente per IEnumerable ... – flq

+0

Grazie per la risposta. Sì, sono possibili le LinkedList basate su struct? E hai un'idea del motivo per cui non esiste una opzione di array basato su Safe stack in .NET? – Bob

+0

@Frank: non è possibile farlo: quando provo a compilare una struttura ricorsiva, ottengo un 'CS0523: membro Struct causa un ciclo nel layout della struttura' – thecoop

0

La cosa più vicina che posso pensare a un array basato su stack sarebbe una struttura annidata manualmente; per una matrice di dimensione N^M, la dimensione del codice sarebbe O (MN) e il tempo di accesso O (M); uno può scalare M e N come conveniente (ad esempio, uno può gestire un array di 4096 elementi come strutture a 4 elementi nidificati a sei profondità, strutture a 8 elementi a quattro profondità o strutture a 16 elementi a tre profondità, a due profondità Strutture a 64 elementi, ecc.) Se si volesse fare un nesting a tre profondità di array a 16 elementi (probabilmente il trade-off più pratico) si definirebbe una struttura a 16 elementi con campi da f0 a f15 e un metodo di accesso che utilizza interruttore/caso per selezionare un elemento. Si potrebbe quindi definire una struttura a 16 elementi di quelli, una struttura a 16 elementi di quelli, ecc.

In generale, l'uso di una matrice standard è meglio che utilizzare strutture di tipo valore per imitare gli array, ma lì sono momenti in cui avere una cosa dell'array-ish come un tipo di valore sarebbe vantaggioso. I vantaggi degli array di tipo value tendono ad essere limitati in .net, tuttavia, da alcune limitazioni nella sua gestione della manipolazione dei tipi di valore per riferimento. Mentre sarebbe bello se si potesse semplicemente accedere all'elemento 0x123 da un array descritto come sopra scrivendo "MyArrayishThing [1] [2] [3]", sarebbe inefficiente per la lettura e inefficace per la scrittura (dal momento che la sottoespressione MyArrayishThing [1 ] farebbe una copia delle strutture che contengono 256 elementi dell'array). Invece, è necessario passare MyArrayishThing [1] facendo riferimento a una routine che può accedere all'elemento 2 di quello e passarlo per riferimento a una routine per accedere all'elemento 3 di quello. È possibile farlo in modo efficiente, ma il codice sembra piuttosto brutto.