Referencja do stringu jako pole w klasie

0

Cześć, mój problem wygląda tak, że w konstruktorze klasy przekazuję referencję do jakiegoś stringa. Potem obiekt tej klasy w pewnym momencie ma mi zmienić wartość w tym właśnie stringu. Nie wiem, jak to ugryźć. Nigdy nie ogarniałem wskaźników w C#, a pewnie istnieje jakiś bardziej przyjazny sposób.

class Changer
{
  string m_string; //ten string ma być referencją do tego przekazanego w konstruktorze - jak tu trzymać referencję?

  public Changer(ref string str)
  {
    m_string = str; //jak tu przekazać referencję?
  }

  public void Foo()
  {
    m_string = "Nowa wartość";
  }
}

Efektem tego ma być, że jak zrobię coś takiego:

 
string str = "Blabla";

Changer changer = new Changer(ref str);
changer.Foo();

to zmienna str będzie miała wartość "Nowa wartość".
Uprzedzając pytania, w rzeczywistości metoda Foo nie jest metodą publiczną i jest wywoływana po prostu w pewnym momencie.

Przy czym wiem, że stringa jako tako nie można zmienić (tylko tworzy się nowy w innym miejscu w pamięci), ale nie zależy mi na tym. Zależy mi, żeby na koniec str miał inną wartość.

0
  • czemu przekazujesz referencje stringa? Przeciez jezeli zmienisz ten obiekt to i tak powstaje nowy obiekt. Nie widze zadnego praktycznego zastosowania do takiego tworu. Duzo lepiej zrobic po prostu funkcje ktora zmienia Ci stringa i przypisac zmieniona wartosc

  • Referencja to nie wskaznik. Wskazniki masz tylko w unsafe mode

  • Jezeli bardzo chcesz zrobic to co chcesz zrobic, to uzyj sobie eventow.

0

Może powiem, co chcę zrobić.

Wyobraźcie sobie wizarda jako swego rodzaju maszynę stanów. I teraz tak. Każda karta wizarda jest osobnym stanem. Gdy użytkownik kliknie "Następny" lub "Poprzedni" zmienia się stan. Ale przejścia między stanami nie są oczywiście sztywne.

Przykład, jak by to miało działać:

//tworzę sobie jakąś klasę, która przechowuje pewne dane (w tym stringi)
Data data = new Data();

//teraz tworzę poszczególne stany
StartPage start = new StartPage(); //początek
FinishPage finish = new FinishPage(); //koniec

//i strony do wyboru katalogów: firstDir i secondDir
SelectDirPage selectFirstDir = new SelectDirPage(ref data.firstDir); //firstDir to string
SelectDirPage selectSecondDir = new SelectDirPage(ref data.secondDir); //secondDir to też string

//i teraz tworzę łańcuch stanów
wizardManager.SetFirstState(start); //początek
wizardManager.SetLastState(finish); //koniec

//teraz efektem będzie to, że pojawi się strona Start, a po wciśnięciu DALEJ, pojawi się strona ostatnia.
//Ale ja chcę, żeby pod pewnymi warunkami pojawiły się inne strony.

//Jeśli zmienna firstDir jest pusta, to wtedy ma się pokazać strona z wyborem katalogu
start.RegisterNextStateOnCondition(data.firstDir == "", selectFirstDir);

selectFirstState.RegisterNextStateOnCondition(data.secondDir == "", selectSecondDir); //jeśli nie ma secondDir, to pokaż znowu stronę do wyboru
selectFirstState.RegisterNext(finish); //domyślnie pokaż ostatnią stronę

selectSecondDir.RegisterNext(finish);

wizardManager.execute(); //ruszamy maszynę

I teraz tak, mógłbym tutaj wchodzić w zdarzenia, ale bardzo szybko zrobi się bałagan, którego chcę uniknąć. Dlatego właśnie potrzebuję w jakiś sposób przekazać tego stringa do zmiany do obiektu klasy SelectDirPage. Oczywiście zauważcie, że są dwa obiekty tej klasy z dwoma różnymi stringami do zmiany.

Mógłbym jeszcze zrobić tak, że na koniec po wszystkim przyrównuję, np:

data.firstDir = selectFirstState.SelectedDir;

Ale problem jest taki, że obiekt data jest przekazywany do wizardManagera i inne stany muszą mieć dostęp do AKTUALNYCH pól tego obiektu.

0

Chyba jedynym sensownym wyjście będzie nie trzymanie typów prostych, tylko opakowanie ich we wrappery.

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