Capítulo 7: Instrucciones de uso de matrices

Publicado: 26 de junio de 2006

Patterns & Practices
Microsoft Corporation
Diciembre de 2002

imagen

https://msdn.microsoft.com/practices/

Para obtener una descripción general de matrices y del uso de matrices, vea Matrices y System.Array (Clase).

En esta página

Capítulo 7: Instrucciones de uso de matrices Capítulo 7: Instrucciones de uso de matrices

Capítulo 7: Instrucciones de uso de matrices

Matrices y Colecciones

En algunas ocasiones, los diseñadores de bibliotecas de clases tienen que decidir entre utilizar una matriz o devolver una colección. Aunque estos tipos tienen modelos de uso similares, las características de rendimiento son diferentes. En general, se debería usar una colección cuando se pueden utilizar métodos como Add, Remove u otros para manipularla. Para obtener más información sobre la utilización de colecciones, vea Agrupar datos en colecciones.

Usar matrices

No se debe devolver una instancia interna de una matriz, ya que esto permite al código llamador cambiar la matriz. El ejemplo siguiente muestra cómo la matriz badChars puede ser modificada por cualquier código que tenga acceso a la propiedad Path aunque la propiedad no implemente el descriptor de acceso set.

[Visual Basic]

Imports System
Imports System.Collections
Imports Microsoft.VisualBasic

Public Class ExampleClass
   NotInheritable Public Class Path      
      Private Sub New()
      End Sub

      Private Property Path
         Get
         End Get
         Set
         End Set
      End Property

      Private Shared badChars() As Char = {Chr(34),"<"c,">"c}
      
      Public Shared Function GetInvalidPathChars() As Char()
         Return badChars
      End Function

   End Class
   
   Public Shared Sub Main()
      ' The following code displays the elements of the 
      ' array as expected.
      Dim c As Char
      For Each c In  Path.GetInvalidPathChars()
         Console.Write(c)
      Next c
      Console.WriteLine()
      
      ' The following code sets all the values to A.
      Path.GetInvalidPathChars()(0) = "A"c
      Path.GetInvalidPathChars()(1) = "A"c
      Path.GetInvalidPathChars()(2) = "A"c
      
      ' The following code displays the elements of the array to the
      ' console. Note that the values have changed.
      For Each c In  Path.GetInvalidPathChars()
         Console.Write(c)
      Next c

   End Sub
End Class

[C#]

using System;
using System.Collections;

public class ExampleClass
{
   public sealed class Path
   {
      private Path(){}
      private static char[] badChars = {'\"', '<', '>'};
      public static char[] GetInvalidPathChars()
      {
         return badChars;
      }
   }
   public static void Main()
   {
      // The following code displays the elements of the 
      // array as expected.
      foreach(char c in Path.GetInvalidPathChars())
      {
         Console.Write(c);
      }
      Console.WriteLine();

      // The following code sets all the values to A.
      Path.GetInvalidPathChars()[0] = 'A';
      Path.GetInvalidPathChars()[1] = 'A';
      Path.GetInvalidPathChars()[2] = 'A';

      // The following code displays the elements of the array to the
      // console. Note that the values have changed.
      foreach(char c in Path.GetInvalidPathChars())
      {
         Console.Write(c);
      }
   }
}

El problema del ejemplo anterior se puede corregir aplicando a la colección badChars readonly (ReadOnly en Visual Basic). Como alternativa, se puede clonar la colección badChars antes de devolverla. En el ejemplo siguiente se muestra cómo modificar el método GetInvalidPathChars para devolver un clon de la colección badChars.

[Visual Basic]

Public Shared Function GetInvalidPathChars() As Char()
   Return CType(badChars.Clone(), Char())
End Function

[C#]

public static char[] GetInvalidPathChars()
{
   return (char[])badChars.Clone();
}

No se deben usar campos readonly (ReadOnly en Visual Basic) de matrices. Si se hace, la matriz será de sólo lectura y no podrá cambiarse, pero sí se podrán modificar los elementos que la componen. En el siguiente ejemplo se muestra cómo se pueden cambiar los elementos de la matriz de sólo lectura InvalidPathChars.

[C#]

public sealed class Path
{
   private Path(){}
   public static readonly char[] InvalidPathChars = {'\"', '<', '>','|'}'
}
//The following code can be used to change the values in the array.
Path.InvalidPathChars[0] = 'A';

Usar propiedades indizadas en colecciones

Sólo debe utilizar una propiedad indizada como miembro predeterminado de una interfaz o una clase de la colección. No cree familias de funciones en tipos que no sean una colección. Un modelo de métodos, como Add, Item y Count, indica que el tipo debe ser una colección.

Propiedades con valores de matrices

Utilice las colecciones para evitar que el código funcione mal. 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 bucle.

[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]);

Para obtener más información, vea el tema Propiedades y métodos.

Devolver matrices vacías

Las propiedades String y Array no deben devolver nunca una referencia nula. Este valor puede resultar difícil de comprender en este contexto. Por ejemplo, un usuario puede suponer que el siguiente código funcionará.

[Visual Basic]

Public Sub DoSomething()
   Dim s As String = SomeOtherFunc()
   If s.Length > 0 Then
      ' Do something else.
   End If
End Sub

[C#]

public void DoSomething()
{
   string s = SomeOtherFunc();
   if (s.Length > 0)
   {
      // Do something else.
   }
}

La regla general es que las matrices nulas, las matrices con cadenas vacías (") y las matrices vacías (0 elementos) deben ser tratadas del mismo modo. Devuelva una matriz vacía en vez de una referencia nula.

Vea también

Instrucciones de diseño para programadores de bibliotecas de clases