Passing C # reference parameters

I have a code that doesn't work, I would appreciate any help you guys can provide me

the code below throws an exception ... but I would have thought that this is not the case if I misinterpret the semantics of ref.

EDIT: thanks for the whole answer ... I know that I am creating a new Queue object in the One.Produce method ... but this is what I really want to do, I would like Main._queue to take a link to One._queue. Is this even possible?

using System;
using System.Collections.Generic;

namespace ConsoleApplication2
{
    class One
    {
        Queue<string> _queue;

        public One(ref Queue<string> queue)
        {
            // should be assigning by reference
            _queue = queue;
        }

        public void Produce()
        {
            _queue = new Queue<string>();
            _queue.Enqueue("one");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Queue<string> _queue = new Queue<string>();

            One one = new One(ref _queue);
            one.Produce();

            // this generates an exception, since _queue is empty
            // i'd have thought _queue would have one item, "one"
            string value = _queue.Dequeue();
        }
    }
}
+3
source share
8 answers

, Produce Queue One._queue; , One._queue . _queue Queue<string>, .

, Produce, :

public void Produce() {
        _queue.Enqueue("one");
}

, _queue , , . , .

public One(Queue<string> queue) {
    _queue = queue;
}

, , _queue Queue<string> One.

+3

:

    public One(Queue<string> queue)
    {
        // should be assigning by reference
        _queue = queue;
    }

    public void Produce()
    {
        _queue.Enqueue("one");
    }
+1

Produce() :

_queue = new Queue<string>();

.

+1

one.Produce() _queue "" Queue(). = _queue.Dequeue() (b/c _queue)

0

Produce:

_queue = new Queue<string>();

Queue<String>, Queue<String>.

0

, ref , . , Main One, Produce.

One . Produce .

, , , , . , _queue Main, .

. One ( " " ) , ref . queue = _queue;, ref .


A - Holder<T> class

, , Holder :

public class Holder<T> {
    public T { get; set; }
}

One Holder<Queue<string>>. Main Holder<Queue<string>>. , One , Main.

, . , , . ? ? , , .


B -

. #, . , .


C -

Your own answer gave me an idea for a third possible solution. It is inherently very similar to the other two solutions. Instead of explaining it in English, let me show it in C #.

class One
{
    Queue<string>[] queueArray;

    public One(Queue<string>[] queueArray)
    {
        if (queueArray == null) throw new ArgumentNullException("queueArray");
        if (queueArray.Length != 1) throw new ArgumentException("queueArray must have one and only one item");
        this.queueArray = queueArray;
    }

    public void Produce()
    {
        queueArray[0] = new Queue<string>();
        queueArray[0].Enqueue("one");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var queueArray = new Queue<string>[] { new Queue<string>() };

        One one = new One(queueArray);
        one.Produce();

        string value = queueArray[0].Dequeue(); //this line sets "one" to value
    }
}
0
source

Why don't you just do the following:

public void Produce()
{
    _queue.Clear();
    _queue.Enqueue("one");
}
0
source

A general approach for this kind of problem .... execute the code using the debugger and see which line throws an exception.

-1
source

Source: https://habr.com/ru/post/1721838/


All Articles