quinta-feira, fevereiro 19, 2009

Parâmetros por referência em C#

Se não tivermos atenção ao que fazemos às vezes podemos apanhar algumas partidas. Vamos analisar um caso simples de modo a poder demonstrar que pequenas alterações podem conduzir a resultados finais totalmente diferentes.

      static void Main(string[] args)
      {
          IList list = new List();
          IList list2 = new List();
          IList list3 = new List();

          list.Add("a");
          list2.Add("a");
          list3.Add("a");

          AddToList(list);
          AddToList2(list2);
          AddToList3(ref list3);

          Console.WriteLine("List 1 count = {0}", list.Count);
          Console.WriteLine("List 2 count = {0}", list2.Count);
          Console.WriteLine("List 3 count = {0}", list3.Count);
      }

      private static void AddToList(ICollection list)
      {
          list.Add("b");
          list.Add("c");
      }

      private static void AddToList2(ICollection list)
      {
          list = new List();
          list.Add("b");
          list.Add("c");
      }

      private static void AddToList3(ref IList list)
      {
          list = new List();
          list.Add("b");
          list.Add("c");
      }
O objectivo é acertar nos valores que vão aparecer no output da consola. Sabendo que em C# as listas são passadas por referência vamos analisar o código de modo a perceber qual vai ser o output.

No primeiro caso à lista que é passada no parâmetro são adicionados mais dois elementos, logo é espectável que o seu count seja 3, pois a referência da lista está a ser partilhada dentro e fora do método.

No segundo caso antes de se adicionarem os elementos à lista está a haver uma nova referenciação, logo a referência à qual estão a ser adicionados os 2 elementos é à referência interna do método, logo fora do método a referência manterá só 1 elemento.

No último caso ao ser colocada a palavra reservada ref, estamos a dizer que a referência é partilhada tanto dentro como fora do método, ou seja, tudo o que fizermos ao objecto inicial dentro do método irá ser repercutido para fora do mesmo. Com isto podemos concluír que no output a list3 terá 2 elementos.

Sem comentários: