Elementy kolekcji przekazywane do funkcji z parametrem "ref"

0

Czy istnieje w C# możliwość przekazania referencji do elementu ArrayList jako argumentu funkcji? Wyobraźmy sobie, że mamy przykładową funkcję rekurencyjną oraz kolekcję typu Arraylist przechowywującą obiekty jakiejś klasy, które wspólnie tworzą pewną strukturę hierarchiczną. (coś jak drzewo binarne) Funkcja powinna pobierać element kolekcji o danym indeksie (jako ref), sprawdzać go, i albo jakoś modyfikować jego atrybuty, albo wywoływać samą siebie dla elementu o pewnym innym indeksie. Niestety, kompilator wyświetla komunikat: "A property or indexer may not be passed as an out or ref parameter". W jaki sposób mógłby taką przeszkodę ominąć ktoś, kto właśnie potrzebowałby funkcji modyfikującej obiekty przechowywane w ArrayList?

W formie pseudokodu wyglądałoby to mniej więcej tak:


ArrayList obiekty = new ArrayList(); // przechowuje obiekty klasy JakaśKlasa

class JakasKlasa // element drzewa
{
	int c1;
	int c2;
	bool CzyLisc;
	string nazwa;
}

void OznaczLiscie(ref object o) // wyszukuje liście drzewa i zmienia ich pole "nazwa"
{
	if ( ((JakasKlasa)o).CzyLisc == true ) ((JakasKlasa)o).nazwa+=" (jest liściem)";
	else
	{
		OznaczLiscie(ref obiekty[c1]);
		OznaczLiscie(ref obiekty[c2]);
	}
}

int main()
{
	OznaczLiscie(ref obiekty[0]); // obiekt[0] jest korzeniem
}

Oczywiście, funkcja nie musi spełniać dokładnie takiego zadania jak pokazuje powyższy pseudokod - to tylko taki abstrakcyjny przykład mający pokazać w jaki sposób ma ona dojść do celu.

1

Najpierw to co zaburza tutaj obraz tego co chcesz zrobić:

  1. Masz "globalną" kolekcję, a jej elementy przekazujesz przez referencję. Wystarczą indeksy tak na prawdę.
  2. Używasz ref dla obiektu, tylko nie wiem po co. W tym przypadku oznacza to, że chcesz manipulować na kolekcji, a nie na obiekcie i jego właściwościach. Ref na obiekcie ma sens, jeżeli chcesz w środku utworzyć nowy obiekt - operatorem new (chociaż ja używam go jednak u siebie, żeby zaznaczyć że właściwości obiektu będą zmieniane w ciele metody). Przykład:
    public class Test
    {
        public static void Main(string[] args)
        {
            SimpleClass obj = new SimpleClass { number = 5 };
            Change(obj);
            Console.WriteLine(obj.number);
            Console.ReadKey();            
        }

        static void Change(SimpleClass obj)
        {
            obj = new SimpleClass { number = 6 };
        }
    }
    class SimpleClass
    {
        public int number;
    }

Wyjście:

5

Żeby na wyjściu uzyskać 6, trzeba użyć właśnie ref.

Ref na właściwościach użyć nie można, bo to jest tak na prawdę metoda która może zwracać na przykład 5, albo "ala ma kota". Jedyne rozwiązanie jakie tu widzę, to usunięcie ref po prostu.

PS. Nie używaj ArrayList. Użyj List<T> zamiast tego.

0

Czemu kombinujesz z arraylist?

class ElementDrzewa
{
    public ElementDrzewa Prawy;
    public ElementDrzewa Lewy;
}

ElementDrzewa korzen = new ElementDrzewa();

1 użytkowników online, w tym zalogowanych: 0, gości: 1