Dostęp do prywatnej metody klasy zagnieżdżonej

0

Cześć,
Czy istnieje w c# jakiś sposób (podobnie jak w Javie) dla podanego poniżej przypadku, umożliwiający dostęp do metody Update() klasy Velocity wewnątrz klasy Ball i brak dostępu z poza klasy Ball (klasa Window w innym pliku)?

Klasa Ball, z zagnieżdżoną klasą Velocity:

namespace MyNamespace {
    class Ball {
        public class Velocity {
            public double X { get; private set; }
            public double Y { get; private set; }
            public double Z { get; private set; }
            public double A { get; private set; }
            public double B { get; private set; }
            public double C { get; private set; }

            private void Update(Position currentPosition, double deltaTime) {
                /* pewne obliczenia */
            }
        }

        public Velocity CurrentVelocity { get; private set; } = new Velocity();

        public void Update() {
            Position currentPosition = /* pewne obliczenia */;
            double deltaTime = /* pewne obliczenia */;

            CurrentVelocity.Update(currentPosition, deltaTime); //Błąd, metoda Update w klasie Velocity jest niewidoczna. Tutaj dostęp do metody Update powinien być możlowy
        }
    }
}

Klasa Window, zdefiniowana w osobnym pliku:

namespace MyNamespace {
    class Window {
        private Ball ball;

        public Window() {
            ball = new Ball();
            ball.CurrentVelocity.Update(); //Tutaj dostęp do metody Update powinien być zablokowany
        }

    }
}

Wiem że istnieje modyfikator dostępu internal, jednak w powyższym przykladzie metoda Update() klasy Velocity jest wtedy również dostępna w klasie Window:

namespace MyNamespace {
    class Ball {
        public class Velocity {

            /* ... */
            
            internal void Update(Position currentPosition, double deltaTime) {
                /* ... */
            }
        }
    }
}
0

Możesz zrobić zamiast

public Velocity CurrentVelocity { get; private set; } = new Velocity();
protected Velocity CurrentVelocity { get; private set; } = new Velocity();

A to co potrzebne wystawić jakoś osobno

0

Utwórz interfejs IVelocity który będzie zawierał metody i właściwości, które chcesz udostępnić na zewnątrz. Zmień CurrentVelocity z auto-właściwości na właściwość o typie IVelocity z backing fieldem private Velocity _currentVelocity.

    class Ball
    {
        public interface IVelocity
        {
            double X { get; }
            ...
            double C { get; }

            // tu nie ma metody Update
        }

        public class Velocity : IVelocity
        {
            public double X { get; private set; }
            ...
            public double C { get; private set; }

            public void Update(Position currentPosition, double deltaTime)
            {
                /* pewne obliczenia */
            }
        }

        private Velocity _currentVelocity = new Velocity();
        public IVelocity CurrentVelocity => _currentVelocity;

        public void Update()
        {
            Position currentPosition = default;
            double deltaTime = 0;

            _currentVelocity.Update(currentPosition, deltaTime);
        }
    }

Choć nie rozumiem czemu korzystasz z zagnieżdżonych klas. Przecież Velocity mógłbyś zrobić niezagnieżdżoną. No ale ok.

1
krypi23 napisał(a):

Czy istnieje w c# jakiś sposób (podobnie jak w Javie) dla podanego poniżej przypadku, umożliwiający dostęp do metody Update() klasy Velocity wewnątrz klasy Ball i brak dostępu z poza klasy Ball (klasa Window w innym pliku)?

Nie, w C# modyfikatory dostępu nie są zepsute, a klas nie używa się zamiast przestrzeni nazw. Jeśli chcesz upubliczniać klasy, to ich nie zagnieżdżaj.
Klas zagnieżdżonych używa się do przesyłania danych między metodami klasy albo do ścisłego powiązania dwóch klas (np. klasy liczącej coś z jej wynikiem).

0

Dziękuje za odpowiedzi, myślę że zastosowanie interfejsu będzie najlepszym rozwiązaniem.
Stworzyłem tą klasę jako zagnieżdżoną, ponieważ zastosowałem podejście jakie zastosowałbym w Javie, myślałem że zagnieżdżenia w c# zadziałają podobnie. Obiekt Velocity docelowo miałby być obiektem tylko do odczytu, utworzonym tylko raz przechowującym aktualne prędkości piłeczki w różnych osiach. Prędkości powinny aktualizować się po odebraniu danych z czujnika i tylko wtedy. Stąd też chciałem zapewnić możliwość aktualizacji tych prędkości tylko i wyłącznie w klasie w której dane z czujnika są odbierane, czyli w klasie Ball.

1

odchodząc od zadanego pytania i zakładając że to faktyczny kod który chcesz użyć - normalnie w tego typu programach czy na przykład w Unity, Vector powinien być strukturą, w dodatku immutable czyli nie zawiera metody "Update" ani żadnej innej która modyfikuje jej stan, a jedynie można stworzyć nowy zupdate'owany wektor i sobie go zapisać w tym samym miejscu - tutaj Twój problem całkowicie znika bo tylko Ball może sobie zapisać nowy wektor u siebie na podstawie starego, stary wektor może spokojnie "wyciec" poza klasę ale żadna inna klasa go nie może zmienić.

W c# możesz też przeciążyć operatory np dodawania, mnożenia itp. co się świetnie nadaje właśnie w wymienionym przypadku i zazwyczaj w klasach matematycznych, są często używane.
Dzięki temu Twój kod mógłby i pewnie powinien wyglądać mniej więcej tak:

CurrentVelocity += direction * deltaTime;

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