Laden...

Klasse mit "Untereigenschaft", die nur aus der umgebenden Klasse genutzt werden kann

Erstellt von Fonsi vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.040 Views
Fonsi Themenstarter:in
6 Beiträge seit 2011
vor 13 Jahren
Klasse mit "Untereigenschaft", die nur aus der umgebenden Klasse genutzt werden kann

Hi Leute,

ich bin neu hier im Forum und auch im C#-Bereich. Ich programmiere schon ein paar Jährchen, allerdings nur mit Visual Basic (.NET) und will nun auf C# umsteigen und auch etwas tiefer in die objektorientierte Programmierung eintauchen.

Ich suche nach ner Lösung für folgendes Problem:
Ich hab ne Klasse "Wetter". Da kann ich ja nun diverse Methoden deklarieren. Ich hätte gern ne Eigenschaft "Vorhersage" mit diversen "Untereigenschaften" wie z.B. Temperatur oder Wind, sodass ich wie folgt darauf zugreifen kann:

Wetter meinwetter = new Wetter();
MessageBox.Show(meinWetter.Vorhersage.Temperatur);

Würd mich über ein paar Anregungen freuen 🙂

D
343 Beiträge seit 2005
vor 13 Jahren

Hallo Fonsi,

die Eigenschaft Vorhersage sollte einfach von einem Typ sein, die diese Eigenschaften bietet.


//Eigenschaft "mit Untereigenschaften"
public Wettervorhersage Vorhersage {get; set;}


class Wettervorhersage
{
public decimal Temperatur {get; set;}
...

}

Programming is like sex: One mistake and
you have to support it your lifetime

Fonsi Themenstarter:in
6 Beiträge seit 2011
vor 13 Jahren

Super, vielen Dank für die schnelle Antwort! Genau danach hab ich gesucht ...

Ist es möglich, dass man auf die Klasse "Wettervorhersage" nur von der Klasse Wetter zugreifen kann?

Wenn meine Klasse "Wetter" fertig ist, werd ich sie auch zur Verfügung stellen 😉

1.361 Beiträge seit 2007
vor 13 Jahren

Hi,
Komplett den Zugriff auf die wettervorhersage zu verweigern geht nicht, denn du möchtest ja von außen gerade über Wetter.Vorhersage.Temperatur auf ein member von vorhersage zugreifen.
Auch sehe ich keine Gefahr, sodass eine Zugriffsbeschränkung wenig Sinn macht.

Wenn du verhindern möchtest, dass man außerhalb deiner Bibliothek vorhersage Objekte erzeugt,hast du im gründe zwei Möglichkeiten.* du erstellst noch ein öffentliches Interface für die vorhersagen, machst aber die konkrete vorhersageklasse internal

  • du machst den konstruktor für vorhersagen internal

Aber wie gesagt, ich sehe keinen Grund für eine Beschränkung.

Beste grüße
zommi

Fonsi Themenstarter:in
6 Beiträge seit 2011
vor 13 Jahren

Ich will damit eigentlich vermeiden, dass Objekte vom Typ "Wettervorhersage" erzeugt werden können. Ich hab den Konstruktor nun mit

private Wettervorhersage();

überschrieben. Danke für die richtige Fährte 👍

4.942 Beiträge seit 2008
vor 13 Jahren

Hallo Fonsi,

damit kann aber niemand diese Klasse nutzen ?(

Wenn du verhindern willst, daß jemand für deine Wetter-Klasse ein neues Wettervorhersage-Objekt erstellen kann, dann benutze einfach


class Wetter
{
  public Wettervorhersage Vorhersage { get; private set; }
}

So kann nur die Wetterklasse ein Wettervorhersage-Objekt erstellen (wegen 'private'), von außen kann dieses Objekt nur gelesen werden (auf Eigenschaften des Wettervorhersage-Objekts kann aber auch von außen schreibend zugegriffen werden, sofern diese Eigenschaften über öffentliche Setter verfügen).
D.h.


meinWetter.Vorhersage.Temperatur = 24;

wäre also möglich.

Informiere dich in deinem C#-Buch genau über die Zugriffsmodifizierer (public, protected, internal, private).
Und der Hinweis von zommi bzgl. 'interface' wäre dann noch die bessere Variante.

Fonsi Themenstarter:in
6 Beiträge seit 2011
vor 13 Jahren

Hmm jetzt komm ich langsam durcheinander. Momentan sieht meine Klasse so aus:

using System;
using System.Net;
using System.Text;
using System.Xml;

namespace yWeather
{
    class yWeather
    {
        /// <summary>
        /// A 2-day forecast
        /// </summary>
        public yForecast Forecast { get; }

        //weitere Eigenschaften und Methoden von yWeather
    }

    class yForecast
    {
        private yForecast();

        //Eigenschaften und Methoden von yForecast
    }
}

Man erstellt also ein Objekt vom Typ yWeather und hat Zugriff auf yWeather.Forecast. Ein Objekt vom Typ yForecast higegen kann man nicht erstellen. Mal davon abgesehen, dass es momentan funkioniert, wie es soll: Macht das so Sinn oder ist eine andere Lösung sinnvoller?

1.044 Beiträge seit 2008
vor 13 Jahren

Halo Fonsi,

abgesehen davon, dass der Getter von yForecast etwas zurückgeben muss und dass die Namen nicht nach den Richtlinien sind, ist alles okay. Wie schon Th69 sagte, sind private Konstruktoren fehl am Platze. Erstell immer Instanzen, sonst kommt es zu einer NullReferenceException. Mehr findest du hier [FAQ] NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.

An deiner Stelle würde ich mich mit den Grundlagen der OOP befassen. :rtfm:

zero_x

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo zero_x,

Wie schon Th69 sagte, sind private Konstruktoren fehl am Platze.

da kann ich weder Th69 noch dir zustimmen. Private Konstruktoren haben ihre Berechtigung und natürlich können auch zu solchen Klassen Objekte erstellt werden, nur eben nicht durch den "Aufruf" des Konstruktor von außen. Und genau das ist es ja, was Fonsi verhindern will. Also kein Grund, ihm private Konstruktoren ausreden zu wollen.

herbivore

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo herbivore,

private Konstruktoren haben ihre Berechtigungen - da hast du voll und ganz recht. In dem Beispiel von Fonsi halte ich das für eine sehr schlechte Idee! Mal ehrlich: Es wird mehr für Verwirrung sorgen. Produktiv ist es nicht, viel mehr ein Anti-Pattern. Fonsi möchte ja nichts anderes, als sich durch Properties "durchzuhangeln". Wenn man paar Klassen nimmt und in den Properties andere Klassen bereistellt, ist es viel einfacher. Bevor ich jetzt auf die Nachteile eingehe, möchte ich wissen, wo du die Vorteile siehst.

zero_x

1.378 Beiträge seit 2006
vor 13 Jahren

Ich würd das auch mit einer nested private class oder internal(wenns in einer eigenen Assembly ist) lösen.


    class yWeather
    {
        public yWeather()
        {
            Forecast = new yForecast();
        }

        public IForecast Forecast { get; private set; }

        private class yForecast : IForecast
        {
            
        }
    }

    public interface IForecast
    {

    }

Lg XXX

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo zero_x,

Produktiv ist es nicht, viel mehr ein Anti-Pattern.

ich verstehe nicht, wie du zu so unhaltbaren Aussagen kommst.

... und in den Properties andere Klassen bereistellt, ist es viel einfacher

Genau das tut er doch.

Bevor ich jetzt auf die Nachteile eingehe, möchte ich wissen, wo du die Vorteile siehst.

Es ist doch vollkommen legitim, die Möglichkeit bestimmte Objekte zu erzeugen, nur einer bestimmten Klasse zuzugestehen. Das gibt es auch im .NET Framework, dass man Objekte bestimmte Klassen nicht selbst erstellen kann. Um nichts anderes geht es hier doch.

herbivore

L
416 Beiträge seit 2008
vor 13 Jahren