Design Frage



  • Ok, ich geb's auf. Evtl. einfach mal nach "c# internal friend" googeln, vielleicht fällt dann der Cent.

    <bitte hier Picard vorstellen, der resignierend den Kopf in seiner Hand verbirgt> 😉



  • internal verbirgt nicht den Zustand, des Objektes sondern schränkt die Sichtbarkeit außerhalb der Assembly ein. Ich will zwei Klassen nicht in eine Assembly auslagern, nur weil ich erreichen will, dass sie miteinander kommunizieren können und andere mit ihnen nicht. also ist's hier bullshit.

    Und das "es genau für diesen Fall da ist" verstehe überhaupt nicht. Was ist denn der Fall? [BUZZ]information hiding[\BUZZ]?

    Grantopalen.



  • hajb schrieb:

    internal verbirgt nicht den Zustand, des Objektes sondern schränkt die Sichtbarkeit außerhalb der Assembly ein. Ich will zwei Klassen nicht in eine Assembly auslagern, nur weil ich erreichen will, dass sie miteinander kommunizieren können und andere mit ihnen nicht. also ist's hier bullshit.

    Und das "es genau für diesen Fall da ist" verstehe überhaupt nicht. Was ist denn der Fall? [BUZZ]information hiding[\BUZZ]?

    Grantopalen.

    Danke, genau darum gehts mir, ich will das selbe wie in C++ mit friend nur in C# erreichen, anscheint gibt es dafür kein passendes Pattern, muss ich mir mal selber was überlegen.



  • internal verbirgt nicht den Zustand, des Objektes sondern schränkt die Sichtbarkeit außerhalb der Assembly ein.

    und verbirgt damit den Zustand außerhalb der Assembly.

    Ein C++ friend gibt es schlicht weg nicht. Entweder man überdenkt sein Design so lange bis man kein friend mehr braucht oder verwendet eine eigene Assembly mit friend. Innerhalb der Assembly kann man dann "intern" machen was man will denn "intern" hat man die Kontrolle über den Zustand und kann auch mal dinge erlauben die man öffentlich nicht erlauben will.

    Wie auch immer, um eckige Klötzchen doch durch runde Löcher zu bekommen kann auch noch nen Hammer nehmen: Reflection.



  • Knuddlbaer bringt's auf den Punkt.

    Will man friend in C# möglichst genau nachbilden, dann -> internal.

    Will man friend möglichst genau per OO nachbilden, dann z.B. so wie es Andorxor auf Seite 2 schon gezeigt hat, oder z.B. so...

    public interface IMayChangeAWert {
        int NewAWert { get; }
      }
    
      public class A {
        private int p_Wert;
    
        public int Wert { get { return p_Wert; } }
        public void ChangeWert( IMayChangeAWert changer ) {
          // So...
          p_Wert = changer.NewAWert;
    
          // ...oder auch so (nur Bs erlaubt)
          if( changer is B ) {
            p_Wert = changer.NewAWert;
          }
        }
      }
    
      public class B : IMayChangeAWert {
        private A p_A;
        private int p_Wert = 42;
        private bool p_WertAvailable = false;
    
        private void Do() {
          p_Wert = p_A.Wert;
          p_Wert++;
          p_WertAvailable = true;
          p_A.ChangeWert( this );
          p_WertAvailable = false;
        }
    
        public bool WertAvailable { get { return p_WertAvailable; } }
        public int NewAWert {
          get {
            if( p_WertAvailable ) return p_Wert;
    
            // verhindern, dass der Wert von außerhalb abgefragt wird
            throw new InvalidOperationException( "Nene" );
          }
        }
      }
    

    Am besten ist aber, man überdenkt sein Design nochmal, wenn man glaubt unbedingt einen "friend" zu benötigen, denn meißt steckt ein Designfehler dahinter.

    In diesem Thread wurden nun schon mindestens 3 Lösungen für das Problem genannt und du (Firestarter) fragst immer noch nach einem Pattern... Nun, gut, dann so: es wurden schon zwei Pattern genannt: Das Andorxor-Pattern und das Solid-Pattern. 😉



  • SolidOffline schrieb:

    Knuddlbaer bringt's auf den Punkt.

    Will man friend in C# möglichst genau nachbilden, dann -> internal.

    Will man friend möglichst genau per OO nachbilden, dann z.B. so wie es Andorxor auf Seite 2 schon gezeigt hat, oder z.B. so...

    public interface IMayChangeAWert {
        int NewAWert { get; }
      }
    
      public class A {
        private int p_Wert;
    
        public int Wert { get { return p_Wert; } }
        public void ChangeWert( IMayChangeAWert changer ) {
          // So...
          p_Wert = changer.NewAWert;
    
          // ...oder auch so (nur Bs erlaubt)
          if( changer is B ) {
            p_Wert = changer.NewAWert;
          }
        }
      }
    
      public class B : IMayChangeAWert {
        private A p_A;
        private int p_Wert = 42;
        private bool p_WertAvailable = false;
    
        private void Do() {
          p_Wert = p_A.Wert;
          p_Wert++;
          p_WertAvailable = true;
          p_A.ChangeWert( this );
          p_WertAvailable = false;
        }
    
        public bool WertAvailable { get { return p_WertAvailable; } }
        public int NewAWert {
          get {
            if( p_WertAvailable ) return p_Wert;
    
            // verhindern, dass der Wert von außerhalb abgefragt wird
            throw new InvalidOperationException( "Nene" );
          }
        }
      }
    

    Am besten ist aber, man überdenkt sein Design nochmal, wenn man glaubt unbedingt einen "friend" zu benötigen, denn meißt steckt ein Designfehler dahinter.

    In diesem Thread wurden nun schon mindestens 3 Lösungen für das Problem genannt und du (Firestarter) fragst immer noch nach einem Pattern... Nun, gut, dann so: es wurden schon zwei Pattern genannt: Das Andorxor-Pattern und das Solid-Pattern. 😉

    Holy Crap 😃 Danke, nun hab ich es doch auch Begriffen, ich danke allen die es so lange ausgehalten haben :p



  • @SolidOffline Der Beispielcode is jetzt aber nich ernst gemeint, oder ?



  • Knuddlbaer schrieb:

    @SolidOffline Der Beispielcode is jetzt aber nich ernst gemeint, oder ?

    Kommt drauf an, was du mit "ernst" meinst. Wenn du damit meinst, ob er im Sinne von "friend" (nach offensichtlichen Änderungen) funktioniert, dann ja. Wenn du damit meinst, ob ich jemals sowas benutzen würde, dann nein. 😉



  • Bin ich beruhigt, letzteres war gemeint.

    Btw.: Im Sinne von Friend ist das immer noch nicht da jede Klasse die von B erbt zugriff erlangt.



  • Knuddlbaer schrieb:

    Bin ich beruhigt, letzteres war gemeint.

    Btw.: Im Sinne von Friend ist das immer noch nicht da jede Klasse die von B erbt zugriff erlangt.

    Jo, das meinte ich mit "offensichtlichen Änderungen". Könnte man auch ohne Interface, direkt auf B umschreiben, dann noch "sealed" auf B und fertisch. So wie er da steht, funktionierts ja sogar mit jeder Klasse, die das Interface IMayChangeAWert implementiert.

    Aber wie gesagt: schön ist das nicht.


Anmelden zum Antworten