Pregunta

De acuerdo con [MSDN: Pautas de uso de matriz] ( http://msdn.microsoft.com/en-us/library/k2604h5s (VS.71) .aspx) :

Propiedades con valor de matriz

  

Debe usar colecciones para evitar ineficiencias de código. En el siguiente ejemplo de código, cada llamada a la propiedad myObj crea una copia de la matriz. Como resultado, se crearán 2n + 1 copias de la matriz en el siguiente ciclo.

[Visual Basic]

Dim i As Integer
For i = 0 To obj.myObj.Count - 1
   DoSomething(obj.myObj(i))
Next i

[C#]
for (int i = 0; i < obj.myObj.Count; i++)
      DoSomething(obj.myObj[i]);

Aparte del cambio de myObj [] a ICollection myObj, ¿qué más recomendaría? Me acabo de dar cuenta de que mi aplicación actual está perdiendo memoria :(

Gracias;

EDITAR: ¿Forzar a C # a pasar referencias w / ref (aparte de la seguridad) mejoraría el rendimiento y / o el uso de memoria?

¿Fue útil?

Solución

No, no es pérdida de memoria , solo está haciendo que el recolector de basura trabaje más de lo que podría. En realidad, el artículo de MSDN es un poco engañoso: si la propiedad creara una nueva colección cada vez que se llamaba, sería tan mala (en cuanto a memoria) como con una matriz. Quizás peor, debido al sobredimensionamiento habitual de la mayoría de las implementaciones de colecciones.

Si sabe que un método / propiedad funciona, siempre puede minimizar la cantidad de llamadas:

var arr = obj.myObj; // var since I don't know the type!
for (int i = 0; i < arr.Length; i++) {
  DoSomething(arr[i]);
}

o incluso más fácil, use foreach :

foreach(var value in obj.myObj) {
  DoSomething(value);
}

Ambos enfoques solo llaman a la propiedad una vez. El segundo es más claro IMO.

Otros pensamientos; nombrarlo un método! es decir, obj.SomeMethod () : esto establece la expectativa de que sí funciona y evita el indeseable obj.Foo! = obj.Foo (que sería el caso de las matrices) .

Finalmente, Eric Lippert tiene un buen artículo sobre este tema .

Otros consejos

Solo como una pista para aquellos que no han usado la ReadOnlyCollection mencionada en algunas de las respuestas:

[C#]

class XY
{
  private X[] array;

  public ReadOnlyCollection<X> myObj
  {
    get
    {
      return Array.AsReadOnly(array);
    }
  }
}

Espero que esto pueda ayudar.

Cada vez que tengo propiedades que son costosas (como recrear una colección en la llamada), o bien documento la propiedad, declarando que cada llamada incurre en un costo, o guardo en caché el valor como un campo privado. Los captadores de propiedades que son costosos deben escribirse como métodos. En general, trato de exponer colecciones como IEnumerable en lugar de matrices, obligando al consumidor a usar foreach (o un enumerador).

No hará copias de la matriz a menos que usted lo haga. Sin embargo, simplemente pasar la referencia a una matriz de propiedad privada de un objeto tiene algunos efectos secundarios desagradables. Quien reciba la referencia es básicamente libre de hacer lo que quiera con la matriz, incluida la alteración de los contenidos de manera que su propietario no pueda controlar.

Una forma de evitar la intromisión no autorizada con la matriz es devolver una copia del contenido. Otra (un poco mejor) es devolver una colección de solo lectura.

Aún así, antes de hacer cualquiera de estas cosas, debe preguntarse si está a punto de dar demasiada información. En algunos casos (en realidad, con bastante frecuencia) es aún mejor mantener la matriz privada y, en su lugar, dejar que proporcionen métodos que operen en el objeto que la posee.

myobj no creará un nuevo elemento a menos que cree uno explícitamente. así que para hacer un mejor uso de la memoria, recomiendo usar una colección privada (Lista o cualquiera) y exponer el indexador que devolverá el valor especificado de la colección privada

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top