Klasa posiadająca do siebie dostęp z poziomu innej klasy

0

Witam. Mam do Was małe pytanko. Mianowicie chodzi mi o sytuację tego typu:

 
public class MainClass
{
	public OtherClass otherClass;
	public MainClass(){
		otherClass = new OtherClass();
	}
}

public class OtherClass
{
	public string property = "null";
	public MainClass mainClass;
	public OtherClass(){
		mainClass = new MainClass();
                //czy taka sytuacja ma prawo zajść???
		mainClass.otherClass.property
	}
}

Chodzi mi miejsce, które okomentowałem. Czy może dojść do takiej sytuacji? Oczywiście nie zamierzam się w ten sposób odwoływać do właściwości/metod. Jest to taki efekt uboczny, który powstał w moim projekcie i zastanawiam się czy mam martwić się jego usunięciem...

Proszę o pomoc.
Pozdrawiam ;)

0

Akurat w Twoim przykładzie konstruktory będą wywoływać się rekurencyjnie w nieskończoność i nastąpi stack overflow, ale jak to jakoś ograniczysz to jest jak najbardziej możliwe.

0

Chciałbym zobaczyć przykład z Twojego projektu. Takie zachowanie nie powinno mieć miejsca. Po co tworzyć takiego potworka:

 
 mainClass.otherClass.property

skoro chcemy odnieść się do właściwości tej samej klasy:

 
this.property
0

Kurcze... tak to jest jak się szybko pisze... ;)

Przykład miał wyglądać tak:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            MainClass mc = new MainClass();
            //ok
            Console.WriteLine(mc.otherClass.property);
            Console.ReadKey();
        }
    }
    public class MainClass
    {
        public OtherClass otherClass;
        public MainClass()
        {
            otherClass = new OtherClass(this);
        }
    }
    public class OtherClass
    {
        public string property = "null";
        public MainClass mainClass;
        public OtherClass(MainClass mainClass)
        {
            this.mainClass = mainClass;
            //o tą sytuacje chodziło
            //exception
            //Console.WriteLine(this.mainClass.otherClass.property);       
        }
    }
}

Cóż, wygląda na to że jednak do takiej sytuacji nie może dojść, bo posypie wyjątkiem :)
Pytanie, czy może tak zostać jeżeli nie będę używał linijki, która wywala wyjątek?

3

Cóż, wygląda na to że jednak do takiej sytuacji nie może dojść, bo posypie wyjątkiem :)

Sypie wyjątkiem, bo Twoje konstruktory tworzą cykl.

W działającym kodzie nie sypnie wyjątkiem:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var mc = new MainClass();
            var oc = new OtherClass(mc);

            //ok
            Console.WriteLine(mc.otherClass.property);
            Console.ReadKey();
        }
    }
    public class MainClass
    {
        public OtherClass otherClass;
        public MainClass()
        {
        }
    }
    public class OtherClass
    {
        public string property = "null";
        public MainClass mainClass;
        public OtherClass(MainClass mainClass)
        {
            this.mainClass = mainClass;
            this.mainClass.otherClass = this;

            Console.WriteLine(this.mainClass.otherClass.property);       
        }
    }
}

Ale ten kod jest ogólnie okropny, np. jeśli chodzi o enkapsulację (nadmiar publicznych pól).

Ogólnie dwa obiekty mogą wzajemnie mieć do siebie referencje, więc w kodzie klasy A, można się odwoływać do pola klasy B będącego typu A. Chociaż wzajemne referencje to mało kiedy dobry pomysł.

0

Podobnie jak koledzy wyzej, uwazam ze to nie fajne rozwiazanie.
Tego rodzaju pomysly maja osoby zaczynajace przygode z C# po wczesniejszym programowaniu w jakims egzotycznym jezyku (via C++) ... dobra zart;

Wiadomo, normalne jest zachowanie gdzie obiekt do ktorego mamy dostep korzysta z innego.
Ale to sie odbywa przez wywolanie metody publicznej w pierwszym obiekcie.

Proponuje zapoznac sie choćby z wzorcem adapter oraz z prawem demeter.

Pawel

Ps.Wiadomo ze sa pewne "przyjete" odstepstwa, (np Linq, Entity). Demeter nie jest jakas zelazna zasada, ale warto miec je w pamieci.

0

Generalnie rzecz biorąc założyłem ten temat, bo zastanawiałem się nad tym jak uzyskać dostęp do "dzieci" ViewModel'u w moim projekcie. Zrobiłem to tak:

public CleanerTabViewModel cleanerTabViewModel;
public SettingsTabViewModel settingsTabViewModel;
public MainWindowViewModel()
{
            _children = new ObservableCollection<object>();
            _children.Add(cleanerTabViewModel =  new CleanerTabViewModel(this));
            _children.Add(settingsTabViewModel = new SettingsTabViewModel(this));
            _children.Add(aboutTabViewModel = new AboutTabViewModel(this));
}

Dzięki temu z poziomu dzieci mam dostęp do MainViewModelu, a z poziomu ViewModelu dostęp do dzieci. Gdzie mogę odnosić się do nich w taki sposób: MainWindowViewModel.CleanerTabViewModel.properties (jeżeli potrzebuję zrobić to z innej klasy. Przykład to klasa SettingsLoader i metody Load i Save).
Czy w tym kontekście jest to dobre rozwiązanie?
https://github.com/lukaszpl/Cleaner.NET/blob/master/Cleaner.NET/ViewModel/MainWindowViewModel.cs

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