Array .Net con limite inferiore > 0
Domanda
Anche se forse è una cosa bizzarra da fare, devo creare un array in .Net con un limite inferiore> 0.Questo a prima vista sembra essere possibile, utilizzando:
Array.CreateInstance(typeof(Object), new int[] {2}, new int[] {9});
Produce i risultati desiderati (un array di oggetti con un limite inferiore impostato su 9).Tuttavia, l'istanza dell'array creata non può più essere passata ad altri metodi in attesa Object[]
dandomi un errore dicendo che:
System.Object[*]
non può essere inserito in a System.Object[]
.Qual è questa differenza nei tipi di array e come posso superarla?
Modificare:codice di prova =
Object x = Array.CreateInstance(typeof(Object), new int[] {2}, new int[] {9});
Object[] y = (Object[])x;
Che fallisce con:"Impossibile eseguire il cast dell'oggetto di tipo 'System.Object[*]' nel tipo 'System.Object[]'."
Vorrei anche sottolineare che questo approccio FA funziona quando si utilizzano più dimensioni:
Object x = Array.CreateInstance(typeof(Object), new int[] {2,2}, new int[] {9,9});
Object[,] y = (Object[,])x;
Il che funziona bene.
Soluzione
Questo articolo lo spiega: http://www.panopticoncentral.net/2004/03/17/non-zero-lower-bounded-arrays-the-other-side-of-the-coin/
Altri suggerimenti
Il motivo per cui non puoi lanciare dall'uno all'altro è che questo è malvagio.
Diciamo che crei un array di oggetto[5..9] e lo passi a una funzione F come oggetto[].
Come farebbe la funzione a sapere che questo è un 5..9 ?F si aspetta un array generale ma ne sta ottenendo uno vincolato.Si potrebbe dire che è possibile che lo sappia, ma questo è ancora inaspettato e le persone non vogliono fare tutti i tipi di controlli sui limiti ogni volta che vogliono usare un array semplice.
Un array è la struttura più semplice nella programmazione, rendendolo troppo complicato lo rende inutilizzabile.Probabilmente hai bisogno di un'altra struttura.
Quello che dovresti fare è una classe che sia una raccolta vincolata che imiti il comportamento che desideri.In questo modo, tutti gli utenti di quella classe sapranno cosa aspettarsi.
class ConstrainedArray<T> : IEnumerable<T> where T : new()
{
public ConstrainedArray(int min, int max)
{
array = new T[max - min];
}
public T this [int index]
{
get { return array[index - Min]; }
set { array[index - Min] = value; }
}
public int Min {get; private set;}
public int Max {get; private set;}
T[] array;
public IEnumerator<T> GetEnumerator()
{
return array.GetEnumarator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return array.GetEnumarator();
}
}
Non sono sicuro del motivo per cui non può essere passato come Object[], ma non sarebbe facile se creassi semplicemente una classe reale per avvolgere un array e gestire la tua "logica strana" lì dentro?
Otterresti i vantaggi dell'utilizzo di un oggetto di riferimento reale se potessi aggiungere "intelligenza" alla tua classe.
Modificare:Come stai trasmettendo il tuo array, potresti pubblicare altro codice?Grazie.
Memorizza semplicemente il limite inferiore in un numero intero con offset const e sottrai quel valore da qualunque cosa la tua fonte restituisca come indice.
Anche:questa è una vecchia funzionalità VB6.Penso che potrebbe esserci un attributo per aiutarlo a supportarlo.