2009-06-28 19 views
9

Estoy usando C#, y es bastante molesto que no pueda enviar una matriz a partir de un cierto punto como en C++.Obtener matriz comenzando con desplazamiento

suponer este código:

int[] array = new int[32]; 
foobar (array + 4); //send array starting from the 4th place. 

esto es una sintaxis extraña para C#, ya que no tenemos punteros utilizables, pero seguro que hay una manera de hacerlo? There's .Skip(), pero creo que produce una nueva matriz, que es algo que no me gusta.

¿Cuáles son mis opciones?

+3

FYI, saltar no produce una nueva matriz. Produce un nuevo _array enumerator_ que se ha saltado las primeras n entradas. –

+1

Lo que he hecho al portar el código C++ a C# que usa este modismo de punteros interiores para una matriz es implementar una estructura ArrayPtr inmutable que implemente operadores definidos por el usuario [] - +. La clase ArrayPtr maneja los detalles de descifrar cuáles son los desplazamientos correctos en la matriz real. –

+0

¿Cómo determinaste que la creación de una nueva matriz implica demasiada sobrecarga? – nos

Respuesta

1

Puede pasar el desplazamiento a la función como parámetro. La función simplemente recorrerá los elementos desde [array + desplazamiento] a array.Length. Eso, o copie la subarreglo en una nueva matriz, pero eso probablemente no sea óptimo.

+1

sí, lo sé, pero es muy feo. – Nefzen

+0

Sí, me gusta más la sugerencia de la televisión, pero no sé "tan feo". Es bastante sencillo, ¿qué piensas de array.Skip está haciendo? –

+0

Lo que pasa es que es propenso a errores – Nefzen

17

Es posible que desee pasarlo como IEnumerable<int> en lugar de como una matriz. Luego puede usar omitir y simplemente moverá el iterador sobre la cantidad de elementos omitidos. Usado de esta manera, no tendrá que usar ToArray() y crear una copia de la porción de la matriz en cuestión. Por supuesto, IEnumerable puede no ser apropiado para lo que quieres hacer, pero eso es difícil de deducir de tu pregunta.

public void FooBar(IEnumerable<int> bar) 
{ 
    ... 
} 

int[] array = new int[32]; 
FooBar(array.Skip(4)); 
+2

¿Cuál es la sobrecarga para convertir una matriz en enumerable? – Nefzen

+6

Zero: las matrices ya implementan IEnumerable tvanfosson

+2

http://msdn.microsoft.com/en-us/library/system.array.aspx En .NET Framework versión 2.0, la clase Array implementa System.Collections.Generic Las interfaces genéricas .IList (T), System.Collections.Generic.ICollection (T) y System.Collections.Generic.IEnumerable (T). Las implementaciones se proporcionan a las matrices en tiempo de ejecución y, por lo tanto, no son visibles para las herramientas de creación de documentación. – tvanfosson

3

puedo apreciar lo que está tratando de hacer, pero no puede (y no debe tratar de) enviar una referencia a "parte de una matriz". En C#, las matrices son objetos, no punteros. Esa es una distinción importante. Enviar una referencia a "parte de un objeto" simplemente no tiene sentido.

¿Cómo debe actuar la "parte de un objeto" cuando la pasa a un método?

  • ¿Qué devolvería array.Length?
  • ¿Qué sucede si el método llamado ordena la matriz (solo es parte de la matriz)?
  • ¿Qué sucede si la matriz es autorreferencial (es decir, los elementos de la matriz hacen referencia a otras partes de la matriz)? ¿De alguna manera está "bloqueado" el acceso a los elementos de la matriz no pasado al método?
  • ¿El método llamado ahora necesita comprobar una bandera para saber si tienen el "objeto completo?" Eso rompería una gran cantidad de código existente.

Si su método necesita sólo una parte de la matriz (y no desea crear una copia local), la mejor solución sería la de pasar la referencia de matriz y cualquier otra información necesaria para acceder a la parte que necesitar.

Disfrute,

Robert C. Cartaino

+0

sí, una referencia de matriz sería buena. El método no necesita saber que está funcionando en un subconjunto de la matriz, solo lee o escribe en ella. Una referencia a una matriz con la misma interfaz sería genial. De hecho, creo que puedo escribirlo yo mismo, pero no creo que valga la pena el gasto adicional. – Nefzen

3

.NET tiene el envoltorio System.ArraySegment - por desgracia, es completamente inútil, ya que no implementa IEnumerable.

+1

Para las buenas noticias: en .NET 4.5, ArraySegment implementará IEnumerable (así como IList). –

+0

@jdv Finalmente. Los tomó suficiente tiempo. –