Pergunta

Então, se eu estou iteração usando um loop foreach e eu tenho um dentro função que leva um argumento do objeto iterado da lista, e digamos que eu defina seu valor como ser diferente. Por que eu não tenho que usar para fora ou ref? Eu pensei que ele só foi aprovada pelo valor se você não usar out ou ref .... eu sei que um ref você deve ter inicializado a variável antes e fora, você apenas tem que ter definido o seu valor antes do retorno do método.

Parece que se você uma iteração através de uma lista e passar um objeto em sua realmente passado por referência. Considere o exemplo a seguir.

Exemplo

class Program
    {
        static void Main(string[] args)
        {

            List<Foo> list = new List<Foo>();
            list.Add(new Foo() { Bar = "1" });
            list.Add(new Foo() { Bar = "2" });



            foreach (var f in list)
            {
                Foo f2 = f; 
                Console.WriteLine("SetFoo Pre: " + f2.Bar);
                SetFoo(f2);
                Console.WriteLine("SetFoo Post: " + f2.Bar);

                Console.WriteLine("SetFooRef Pre: " + f2.Bar);
                SetFooRef(ref f2);
                Console.WriteLine("SetFooRef Post: " + f2.Bar);
                Console.WriteLine("");
            }




            Console.WriteLine("");

            int i = 0;
            // Not using ref keyword
            Console.WriteLine("SetI Pre: " + i);
            SetI(i);
            Console.WriteLine("SetI Post: " + i);

            // Using ref keyword
            Console.WriteLine("SetRefI Pre: " + i);
            SetRefI(ref i);
            Console.WriteLine("SetRefI Post: " + i);
        }


        private static void SetRefI(ref int i)
        {
            i = 3;
            Console.WriteLine("SetRefI Inside: " + i);
        }

        private static void SetI(int i)
        {
            i = 2;
            Console.WriteLine("SetI Inside: " + i);
        }

        private static void SetFooRef(ref Foo f)
        {
            f.Bar = String.Format("{0} :: {1}", f.Bar, "WithRef");
            Console.WriteLine("SetFooRef Inside: " + f.Bar);
        }

        private static void SetFoo(Foo f)
        {
            f.Bar = String.Format("{0} :: {1}", f.Bar, "WithoutRef");
            Console.WriteLine("SetFoo Inside: " + f.Bar);
        }
    }


    class Foo
    {
        public string Bar { get; set; }
    }

Output:

setFoo Pre: 1 setFoo Interior: 1 ::
WithoutRef setFoo Post: 1 WithoutRef
SetFoo Pre: 1 :: WithoutRef setFoo
Interior: 1 :: WithoutRef :: comref
SetFoo Post: 1 WithoutRef :: comref

setFoo Pre: 2 setFoo Interior: 2 ::
WithoutRef setFoo Post: 2 WithoutRef
SetFoo Pre: 2 :: WithoutRef setFoo
Interior: 2 :: WithoutRef :: comref
SetFoo Post: 2 WithoutRef :: comref

SETI Pre: 0 SETI Interior: 2 SetIPost: 0

SetRefI Pre: 0 SetRefI Interior: 3
SetRefI Post: 3

Eu entendo o árbitro com o exemplo inteiro, mas não o acima Foo exemplo objeto iteração.

Obrigado!

Foi útil?

Solução

O referência é passado por valor. Assim, o método ainda pode alterar o conteúdo do objeto, ele só não pode mudar qual objeto a variável refere-se a.

Consulte meu artigo sobre a passagem de parâmetros para muito mais informação, juntamente com o meu artigo sobre tipos de referência e tipos de valor .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top