Design Frage
-
Hehe danke für eure große Anteilnahme, die Postings die ich gelesen habe, haben mir auf jedenfall sehr geholfen, vielen Dank für eure Meinungen.
-
Sagen wir es mal einfach ich will sowas wie in C++ mit
friend
auch in C# machen.Anscheint geht das aber nicht einfach, dachte mir das ich dafür nen Wrapper schreibe, ich werde es euch wissen lassen wenn ich weiter bin.
-
Firefighter schrieb:
Sagen wir es mal einfach ich will sowas wie in C++ mit
friend
auch in C# machen.Anscheint geht das aber nicht einfach, dachte mir das ich dafür nen Wrapper schreibe, ich werde es euch wissen lassen wenn ich weiter bin.Hallo? Jemand zuhause?
Genau dafür ist der Zugriffsmodifizierer "internal" gedacht, wobei die "friends" halt in einer Assembly zusammengefasst werden (dass es auch friend-assemblies gibt, lass ich mal aussen vor). Woran scheitert es denn nun?
-
Öhm da bin ich ehrlich gesagt, nicht der Meinung. Wenn ich in C++ mit friend arbeite, bezieht sich friend einschließlich auf die Klasse in welcher es angwendet wird, wenn ich internal anwende, bezieht es sich auf meine ganze Assembly und es wurde schon in vorherigen Posts korrekt erkkannt wie ich es machen möchte.
NoAir schrieb:
Hallo,"internal" geht nur, wenn er zwei Assemblys hat (.dll + .exe).
Hat er nur eine (.exe) ist "internal" mit "public" gleichgestellt und somit komplett fürn Eimer.Grüße
P.S. Will er eine Lib entwickeln, stellt sich dieses Problem natürlich erst gar nicht. Ich denke jedoch, dass er die 3 Klassen in seinem Projekt benutzen möchte?!
Und friend und internal zeigen in meinen Augen überhaupt nicht das Ergebnis was ich erwarte.Aber anscheint funktioniert es einfach nicht so
Trotzdem danke für die Antworten.
-
jo.
Ich verstehe das so: Dummy soll seinen Zustand verbergen. Vermutlich eine gute Idee. Aber der Zustand ist nicht konstant, denn Actors (und ggf. andere) sollen ja den Zustand ändern können, nur eben nicht beliebig. Dann lass den Dummy das doch selbst machen! Dein Pattern heißt "Methode". Wenn nur bestimmte Dinge nicht gemacht werden dürfen (zb. negative Werte), dann kannst du auch eine Property nehmen und den Wert vor der Zuweisung prüfen.
class Dummy { private int wichtigevariable; public Dumm() { //... } //readonly property wird man vielleicht auch mal brauchen public int WichtigeVariable { get { return wichtigevariable; } } public void TuWas() { //TODO: Add logic here // e.g.: ++wichtigevariable; } } class Holder { private readonly Dummy dummy; public Dummy{ get { return dummy; } } public Holder(Dummy dumm) { dummy=dumm; //...was mit dem Dummy } } class Acter { private Dictionary<int,Holder> dummys; public Acter() { //.... } public void erhoehen(/*irgendwelche parameter*/) { foreach(Holder holder in dummys) { //TODO: Add more logic here holder.Dummy.TuWas(); //TODO: And here } } }
Grantopalen.
-
Hmm das wäre eine Möglichkeit.Danke dir für die ausführliche Antwort.
-
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.