Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Sinn und Unsinn von out
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

Sinn und Unsinn von out

beantworten | zitieren | melden

[EDIT]Abgetrennt von [Artikel] C# und Übergabemechanismen: call by value vs. call by reference (ref/out)[/EDIT]

Hi herbivore, (Hi, Borg natürlich auch :-D)

Wie gesagt ich sage nicht das out kein Sinn macht :-)
Ich finde sogar das (wie Borg das auch sagt) es mit TryParse besser lesbar und schöner als mit einem TryCatch-konstrukt im Code ist oder mit dem Rückgabekonstrukt das Borg vorgeschlagen hat ist.

Der eigentliche Grund wieso wir aber vor diesem Schönheitsproblem stehlen ist static - ein Konzept das vieles einfacher macht und auch übersichtlicher das allerdings der OOP auch nicht gut tut.

Deshalbt funktioniert die Kombination von static und out auch so gut. (im TryParse zB)
Meiner Meinung nach ist static auch der einzige Punkt in einem Program der en out enthalten sollte da sowieso beide Konzepte nicht OO sind kann man sie auch kombinieren um auf einer anderen Ebene zu programmieren als der OO.

Das Problem ist das int eigentlich so aussehen müsste:


class Int32
{
     public bool Parse(string numberAsString)
    {
        // DO CONVERT - THROW EXCEPTION oder ggf return false
        this.value = number; //CONVERTED VAL
        return true;
    }
}
EDIT:
Damit lässt sich dann nämlich auch recht schöner code schreiben.
// je nachdem ob man bool nutzt oder ein void + Exception muss man mit try arbeiten (was dann nichtmehr so schön ist).


string numberAsString = "42";
int container;
if(container.Parse(numberAsString))
{
   //do good stuff
}
else
   //do bad stuff
Daher gilt für mich auch immer OO vor static (und solchen dingen wie out)

Das Objekt Int32 hat also eine Parse Methoode die das Parsing übernimmt und das value überschreibt.
Das Problem damit ist das die Objekte so sehr groß wachsen können.
Daher gibt es eigentlich ja das Convert-objekt.
Ich denke der grund für Parse / TryParse ist das es bequemer ist ein "Punkt" zu schreiben als ein neues Converter Objekt zu erzeugen.

Alles in allem will ich auch nicht streiten wessen Stil wie besser ist - aber ich hoffe doch das Leute die diesen Beitrag finden über die nutzung von out nachdenken.
Offtmals ist es nicht nötig (und auch im Framework nicht sehr oft zu sehen)

(Immer vergess ich was -_-)
private Nachricht | Beiträge des Benutzers
Borg
myCSharp.de - Member



Dabei seit:
Beiträge: 1.529
Herkunft: Berlin, Germany

beantworten | zitieren | melden

Ich stimme dir prinzipiell zu, allerdings ist die Benutzung einer nicht-statischen Parse-Methode nur für Werttypen (struct) sinnvoll. Bei Referenztypen (class) müsste es dann einen entsprechenden Konstruktor geben.
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

Zitat
Original von Borg
Ich stimme dir prinzipiell zu, allerdings ist die Benutzung einer nicht-statischen Parse-Methode nur für Werttypen (struct) sinnvoll. Bei Referenztypen (class) müsste es dann einen entsprechenden Konstruktor geben.

Hey :-)
Ich habe leider nicht in den Regeln gefunden on Artikel als normale Diskussionsplatform gelten (wenn nicht würde ich dich gerne um eine PN antwort bitten :-))

Meine frage ist ein kurzes "Warum?"
Ich verstehe das das verhalten von Referenztypen ein anderes ist als bei Werttypen - nur das ist es doch auch für ganz "normale" arbeiten darauf.

Mir muss klar sein das sich die beiden unterscheiden - trotdem sehe ich nicht was du meinst - das verhalten meiner "Parse"-methode wäre das selbe wie bei einer zuweisung auch.

//Nachtrag zum vorpost ... Convert im Framework ist auch statisch. :-/
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Moooitic,

eine Diskussion, bei der es um den Artikel selbst oder sinnvollen Ergänzungen dazu geht, ist zulässig und sinnvoll. Die aktuelle Diskussion geht mir allerdings zu weit. Deshalb hatte ich auch auf deinen vorigen Beitrag schon nicht geantwortet, obwohl ich durchaus nicht vollkommen deiner Meinung war. Aber ich wollte die Diskussion eben nicht verlängern. Im Zweifel muss ich sie abtrennen, was aber auch blöd ist, weil zu mindest der Anfang hier gut passt. Ich schließe erstmal.

[EDIT]Ok, ich habe mich entschlossen, einen Teil der Diskussion abzutrennen, damit diese hier frei weiter gehen kann ohne den Artikel-Thread zu überlasten.[EDIT]

herbivore
private Nachricht | Beiträge des Benutzers
Borg
myCSharp.de - Member



Dabei seit:
Beiträge: 1.529
Herkunft: Berlin, Germany

statische Methoden bei Wert-/Referenztypen

beantworten | zitieren | melden

Ok, dann poste ich hier noch mal meine PM an Moooitic:
Zitat
Zur Klärung:
Werttypen können auch uninitialisiert benutzt werden, so dass ich einfach das Parse einer "leeren" Instanz aufrufen kann.
Bei Referenztypen muss ich allerdings zwingend einen Konstruktor aufrufen, bevor ich irgendwelche Instanzmethoden aufrufen kann.

Als Code:


struct Werttyp
{
   int val;
   public Referenztyp( int i ) { val = i; }
   public bool Parse( string str ) { // ... }
}

class Referenztyp
{
   int val;
   public Referenztyp( int i ) { val = i; }
   public bool Parse( string str ) { // ... }
}

// Jetzt kann ich den Werttyp so parsen:
Werttyp num1; // deklarieren => Instanz ist uninitialisiert
num1.Parse( myString ); // direkt Wert laden

// Beim Referenztyp muss ich es so machen:
Referenztyp num2 = new Referenztyp(); // deklarieren und initialisieren => Instanz ist initialisiert
num2.Parse( myString );

Der wichtige Unterschied ist also, dass der Referenztyp bereits fertig initialisiert und konstruiert sein muss, bevor ich Instanzmethoden aufrufen kann. Jetzt gibt es aber vielleicht keinen einfachen Konstruktor. Oder er prüft die Parameter. Oder im Konstruktor müssen irgendwelche Ressourcen gebunden werden.
Auf jeden Fall habe ich - falls es mit irgendwelchen Parametern überhaupt gelingt - völlig unnötig die Instanz konstruiert, da sie beim Parse ja wieder ersetzt werden.
Um das zu umgehen, muss man entweder statische Methoden einsetzen, die keine fertige Instanz brauchen, oder Konstruktoren mit verschiedenen Parameterlisten.

Ich ziehe den zweiten Weg vor, allerdings wollte MS wohl keine Konstrukte wie:
int myInt = new int( "1234" );
Außerdem haben wir dort wieder das Problem der Exception bzw. mehrfachen Rückgabewerte.
private Nachricht | Beiträge des Benutzers
Traumzauberbaum
myCSharp.de - Member



Dabei seit:
Beiträge: 512

beantworten | zitieren | melden

Warum ist es denn für OOP natürlich maximal einen Rückgabewert zu haben?

Ein out Parameter ist doch äquivalent zu dem, was man über return zurückgibt.
e.f.q.

Aus Falschem folgt Beliebiges
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

Nein imo nicht,
ein out verändert die Umgebung ein return gibt zurück.

Nehmen wir an du bist ein Automat (für fahrkarten) und ich schmeiße
10 Euro in dich.
Dann ist deine Rückgabe object[] {karte,rückgeld} (simpeles-return)
anders mit out
Dann ist mein Rückgabewert karte und das rückgeld erscheint magischerweise dort wo dein 10 Euroschein vor dem kartenkauf war.

Der Automat arbeitet also nicht (wie alle objekte der realen welt) auf einem input -> output shema sondern verändert auchnoch seine Umgebung.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Moooitic,

doch, es ist das gleiche. Denn im folgenden Code wird i durch f und g im Prinzip auf gleiche Weise geändert. Es wird die "Umgebung" durch beide Aufrufe gleich stark oder gleich wenig beeinflusst. Und da der Aufrufer bestimmt, welche Variablen er für den return-Wert bzw. für out verwendet, kann es auch nicht passieren, dass ohne sein Wissen etwas geändert wird, was er nicht will.


int i;

i = f ();

g (out i);
herbivore
private Nachricht | Beiträge des Benutzers
Borg
myCSharp.de - Member



Dabei seit:
Beiträge: 1.529
Herkunft: Berlin, Germany

beantworten | zitieren | melden

Ich finde es objekt-orientierter, wenn alle Methoden nur auf einem Objekt arbeiten und entsprechend nur ein Objekt zurückgeben.
Prinzipiell macht es ja auch keinen Unterschied, ob ich jetzt verschiedene Variablen bereitstelle, die mir die Methode füllt, oder ob mir die Methode ein Objekt, das alle Rückgabewerte enthält, zurückgibt.
Bei einem out-Wert fällt das auch noch nicht auf. Bei mehreren jedoch ergibt sich ein Verstoß gegen das Gebot der Kapselung, weil zusammengehörige Daten unabhängig gespeichert werden.

Deutlich wird das vielleicht an diesem Beispiel:

public bool ParseIPandPort( string Input, out uint IPAddress, out ushort Port )
// Benutzung:
uint IPAddress; // diese beiden Variablen haben (semantisch) überhaupt nichts
ushort Port; // miteinander zu tun, obwohl sie logisch zusammengehören
if (ParseIPandPort( Input, out IPAddress, out Port ))
{
   // ...
}
Im Gegensatz zu:

public class IPandPort
{
   uint IPAddress;
   ushort Port;
}
public IPandPort ParseIPandPort( string Input )
// Benutzung
IPandPort ipap = ParseIPandPort( Input );
if (ipap != null)
{
   // ...
}

EDIT: Code korrigiert.
EDIT2: Text überarbeitet.
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

Das war auch nicht gemeint. @ herbivore

Die 10 euro in meinem beispiel sollten ja auch verschwinden (keine macht dem Betrug).

Nehmen wir an dein "i" oder mein rückgeld wird auf minus 1 gesetzt - das problem ist das nun das objekt das i enthält crasht weil i NIE minus sein darf.

Es ist in setRueckgeld() (callback) wohl definiert (im return nicht später dazu) in der out variante nicht - daher verändert das objekt "seine umgebung" und "kommuniziert" nicht über rückgaben oder methoden.
Jetzt kann man sagen ja toll i kann aber auch als rückgabe minus sein - richtig aber das oberobjekt hat dies dann provoziert und ist für die rückgabe verantwortlich nun scheib dies mal im out fall (mit 1-3 ijk) auf und sag mir das ist kein schlechter stil.

Was ich meine ist das OO laut allem was ich je gelesen habe bedeutet das Objekte miteinanter kommunizieren können über wohldefinierte schnittstellen.

Allein die wohldefiniertheit ist hier schon nicht gegeben - welches i j k l m wird denn geändert ?

man sollte im fall mehrerer ergebnisse immer ein kontainer nehmen (das ist im framework auch meist so eingehalten objekte oder structs mit 2-4 gettern und settern)

nettes beispiel @ Borg
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Moooitic,

ich denke, du hast da irgendwo einen Denkfehler, ich weiß aber nicht genau wo. In meinem Beispiel wird eine lokale Variable geändert. Es wurde nicht das Objekt geändert, dass f und g aufruft. Und nochmal: Der Aufrufer bestimmt, welche Variablen er für return-Wert bzw. für out verwendet. Die Methode f bzw. g kann also nichts ändern, was der Aufrufer nicht will.
Zitat
Allein die wohldefiniertheit ist hier schon nicht gegeben - welches i j k l m wird denn geändert ?
Und wohldefiniert ist hier natürlich auch alles. Bei return gilt genauso, dass die Methode, die den Wert zurückgibt nicht weiß, welches i, j, k, l oder m geändert wird und es spielt für sie auch keine Rolle. Das ist jedenfalls kein Argument gegen out.

herbivore
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

Nein das stimmt nicht.
Der "Aufrufer" bestimmt im out fall nicht was geändert wird sondern nur was "möglich" ist geändert zu werden - und das ist auch genau die kritik.

In einem Kontainer stecken NUR informationen - diese werden vom aufrufenden objekt ausgewertet.

Es sind jedoch nur informationen die von einem anderen objekt kommen.

in einem out ist NICHT definiert was geändert wird.

Deutlich wird wie schlecht "definiert" die ganze sache ist zB hier.


public bool foo(out int i, out int j)
{
   i = 42;
   // Error
   j = 42;
   return bool
}

Was ist nun wohl im Aufrufenden objekt wohl wenn ein try drum herum war ?
Was würde mit einem Kontainer passieren ?
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Moooitic,

ich verstehe deinen Einwand nicht. Der Aufrufer hat die volle Kontrolle. Wenn er vermeiden will, dass trotz einer Exception z.B. ungewollt eine Instanzvariable geändert wird, dann kann er das tun.


class A
{
   int _i;

   public void DoF ()
   {
      _i = f ();   
   }

   public void DoG ()
   {
      int i;
      g (out i);   
      _i = i;
   }
}
Beides ist semantisch gleichwertig.

herbivore
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

Ja , es geht ja eigentlich auch garnicht um "Sinn und Unsinn" (titel kommt von dir ^^) sondern darum was OO der richtigere Stil wäre.

wenn ich dir jetzt ein goto code schreibe dann könntest du mir auch immer das semantisch equivalente codefragment dazu posten :-)

Ich glaube es gibt eine menge Java erklärungen zu goto und pointern (also dem ahnlichen verhalten wie beim out begriff) die wie ich versuchen zu erklären das out unnötig und nicht OO ist.

Das du sagst out ist wie return ist so einfach nicht richtig.
Ein return ist die antwort darauf das ich gegen die mauer laufe.
Wenn jetzt aber jemand anders gegen die mauer läuft und mir dann die nase weh tut ist das was anderes (weil variable gesetzt in oberklasse).
Natürlich kannst du jetzt sagen das der andere auch meine "istGeggenWandGelaufen()" methode hätte aufrufen können -was so nicht umbedingt stimmt - und natürlich kannst du sagen das der programmierer dafür verantwortlich ist.
Das stimmt auch es geht ja im stil und nicht um müssen.
Ich habe läute schon code schreiben sehen der ref TextBox1 enthalten hat - vielleicht kommt meine abneigung daher - in einem großen projekt bricht dir sowas 297 mal die beine im gegensatz zu wohldefinierten schnittsellen.

Ich sagte auch im vorbeitrag das ich garnicht steiten will ^^
Im gegenteil Borg hat mir sehr schön erklärt warum static ein sinn hat (obwohl ich es nicht als OO ansehe).
Im sinne von TryParse hat out den Sinn der kürzeren Schreibweise. das problem ist wenn man sowas in einem artikel nennt und dazu nicht auf die gefahren hinweist dann findet man es bei nachwüchslern immerwieder weil es "einfacher ist" das mag so auch korrekt ein wenn ich meinen 200 zeiler hinklatsche.

Ich wollte nur den grundgedanken äusern das out nicht wirklich eine andere als die historische bedeutung hat.

Gruß :-)

PS: ich finde dein Beispiel zeigt die schönheit der return Variante ^^'
private Nachricht | Beiträge des Benutzers
Traumzauberbaum
myCSharp.de - Member



Dabei seit:
Beiträge: 512

beantworten | zitieren | melden

Zitat
Original von Moooitic
Nein das stimmt nicht.
Der "Aufrufer" bestimmt im out fall nicht was geändert wird sondern nur was "möglich" ist geändert zu werden - und das ist auch genau die kritik.

Nein das stimmt nicht, ein out Parameter MUSS genauso wie ein return gesetzt werden, bevor die Methode verlassen wird.

Innerhalb einer Methode, die mit out Parametern definiert wurde, besteht absolut kein Unterschied zwischen return und out.

Außerhalb der Methode ist in C# der Unterschied, dass man das Return nicht in einer Variable festhalten MUSS. Wohlgemerkt aber in C#, Iron Python z.B. behandelt die Returns und outs völlig gleich.


Du darfst dich nicht an dem TryParse festhalten, du kritisierst schließlich out im Allgemeinen. Es gibt aber Algorithmen, die haben einfach mehrere Rückgabewerte, z.B. div und mod. Hinter den beiden steht exakt der gleiche Algorithmus, also würde man doppelten Code schreiben, wenn man out verwendet. Das hat schon was von Fanatismus im Namen von OOP gegen eines der Grundideen von OOP zu verstoßen.
Oder man führt ein Objekttyp ein, der Tupel beschreibt. Oder man Verwendet Arrays. Nur was ist der Vorteil? Der Nachteil ist, dass man bei einem Tupel und Array an der Signatur der Funktion erstmal nicht weiß, wieviele Werte zurückgegeben werden, und welche Bedeutung diese haben.
e.f.q.

Aus Falschem folgt Beliebiges
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

Arg, lol,

Ich rede die ganze zeit über ref -_- (daher auch immer der pointer vergleich - out ist ja etwas anders)
(ich hab die beiden mal wieder verwächselt)

In dem Sinn hast du recht "out" ist an sich nichts weiter als ein return mit blödem syntax.
Es ist zwar hässlich das immer feste Variablen überschieben werden aber - wie mans mag. (ich würde es auch nicht nutzen... aber da alle variablen belegt werden müssen ist alles definiert)

Dann entschuldige ich mich natürlich - gegen wohldefinierte mehrfachrückgabe hab ich nichts. ^^

Eine frage bleibt jedoch noch - was passiert in meinem error fall ? s.o (schon das was ich denke oder - die parameter werden nicht am ende überschrieben.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Moooitic,
Zitat
Ja , es geht ja eigentlich auch garnicht um "Sinn und Unsinn" (titel kommt von dir ^^) sondern darum was OO der richtigere Stil wäre.
da würde ich sagen: kommt darauf an. Wenn eine Methode mehrere unabhängige Objekte liefern soll, dann ist out ok. Wenn die Objekte eigentlich zusammengehören, also eine Einheit bilden, wäre es besser eine neue Klasse dafür zu schaffen und ein Objekt dieser Klasse zurück zu geben, wie es Borg oben beschrieben hat.

Machen wir doch mal was anderes. Es gibt ja Programmiersprachen, bei denen man mehrere Objekte returnen kann, also z.B. als Pseudocode:
(i, j) = f ();

int, int f ()
{
   return 1, 9;
}
Wäre das jetzt schlechter oder weniger objektorientiert als wenn man nur einen Returnwert zurückgeben könnte?

herbivore
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Moooitic,

was den Exception-Fall angeht, hast du schon Recht. Da würde der out-Parameter geändert, die Variable bei einem Return nicht. Das ist tatsächlich ein Unterschied ... wenn und nur wenn, die aufgerufene Methode so programmiert ist, dass trotz möglicher Exceptions die out-Parameter frühzeitig ändert. Das sollte sie nicht tun. Wir reden ja über Stil. Und da sage ich einfach, wenn die aufgerufene Methode stilvoll geschrieben ist, gibt es keinen Unterschied zwischen return und out.

herbivore
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

neinnein ,
Ich stimme dir voll zu - es ist OO
Mir würde der gedanke nicht liegen das immer irgentwelche variablen überschrieben werden - ich habe immer dieses input -> output shema im kopf und lasse mir lieber einen kontainer geben.
Aber ich stimme voll zu das beides objektorientiert ist.

In meinem automatenbeispiel würde es zwar immernoch heißen das mein 10 euroschein zu einem 5 er wird - aber zumindest ist durch out der beam vorgang definiert und zwar IMMER auf mein geld.

Ich weiß das mein geld danach anders ist als vorher und muss es erneut zählen oder kann davon ausgehen das es anders ist.

Trotzdem halte ich out in seiner anwendung sehr begrenzt und eigentlich nur für Sinnvoll möglich wenn ich rückgabewerte erwarte von den ich weiß das sie wenn alles glatt geht IMMER zu benutzen sind (keine zusatztests) - alles andere würde dann out seine Funktion nehmen.

Danke danke - sorry wegen meiner falschen denkweise.

// Edit zum post hiervor ja ich denke auch das wenn man die methode schreibt es für out einige Funktionale anwendungen gibt :-D
private Nachricht | Beiträge des Benutzers
Traumzauberbaum
myCSharp.de - Member



Dabei seit:
Beiträge: 512

beantworten | zitieren | melden

Zitat
Original von Moooitic
Arg, lol,

Ich rede die ganze zeit über ref -_- (daher auch immer der pointer vergleich - out ist ja etwas anders)

Damit hab ich schon fast gerechnet, aber dazu möchte ich auch noch was sagen:

Eine dumme Verwendung von Schlüsselworten ist kein Argument gegen die Schlüsselworte, sondern gegen diese Art von Verwendung.

Pointer selbst sind sehr gut mit OOP vereinbar. Man kann einen Pointer genauso als Klasse verstehen, wie ein Array. C++ unterscheidet ja nichtmal zwischen den beiden, und in C# könnte man jedes ref auch durch ein Array ersetzen. Aber ist das dann OOP, nur weil ich das gleiche ohne ref mache?

Sobald du ein normalen Referenztypen übergibst, musst du doch auch damit rechnen, dass die Funktion dieses Objekt verändern kann. Wo ist der Unterschied zu einem Pointer?
e.f.q.

Aus Falschem folgt Beliebiges
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

Ich weiß daher auch die Stil-frage.

Die sache ist das es ganz bestimmte Gründe für referenztypen in programmiersprachen gibt - sehr simpel - laufzeit und speicher.

Und so dumm das jetzt klingen mag das ist auch der einzige grund warum es referenzen gibt.
Deshalb hat man schon zu Java-zeiten versucht dem Menschen dieses werkzeug wegzunehmen zumindest solange es nicht nötig ist.
Das problem ist das eine vollständige entfernung von referenzen der sprache garnicht gut tuen würde.

Referenzen aber durch den "ref" begrif wieder zu fördern finde ich falsch und dazu stehe ich und das er gegenn die OOP verstößt dazu stehe ich auch. (dreh einfach alle out zu ref in dem beitrag hier um ^^)

Die Kommunikation von Objekten sollte in der OOP ganz klar definiert sein durch ref ist sie das definitiv nicht.

Referenzen sind ein meta-sprachmittel das über der OOP liegt.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Moooitic,
Zitat
Die sache ist das es ganz bestimmte Gründe für referenztypen in programmiersprachen gibt - sehr simpel - laufzeit und speicher.

Und so dumm das jetzt klingen mag das ist auch der einzige grund warum es referenzen gibt.
nein, kann ich schon wieder nicht zustimmen. Referenzen gibt es, damit bzw. weil Objekte eine Identität haben. Ein Objekt auf seinen Zustand zu reduzieren, was passieren würde, wenn es keine Referenzen geben würde, wäre gerade ganz und gar nicht objektorientiert. Laufzeit und Speicher sind allenfalls - wenn auch wichtige - Nebeneffekte.

Ob ref ein objektorientiertes Konstrukt sind oder nicht, darüber kann man sich streiten. Ich bin der Meinung, dass ref nicht gegen die Objektorientierung verstößt, wenn es richtig eingesetzt wird. Eine Referenz auf eine Referenz kann hierbei ebenso Sinn machen, wie eine Referenz auf einen Werttyp.

herbivore
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

Uh ?

Naja ich weiß was du meinst -
Wenn ich object a und object b vergleiche sind sie nicht gleich weil ihre Referenzen nicht gleich sind (Identität).
Allerdings sehe ich das als den Nebeneffekt an.
Ich kann mir keine Situation denken die eine Referenz hier nötig macht.
Wenn ich davon ausgehe es gibt vieleviele Überschneidungen von wert-technisch-gleichen Objekten dann muss ich ihnen einafch ein 2tes Merkmal geben mit dem ich sie auseinander halten kann.

(um mal Tierfeindlich zu sein) alle Kühe sehen gleich aus.
Also brenn ich ihnen was auf den Hintern = Eigenschaft hinzugefügt.

Ich kann mir nicht vorstellen das die Identität der Hauptgrund für die bindung an Referenzen ist - das hat ein einfachen pragmatischen Computersinn.

Gruß - sorry wenn ich öfter mal falsch lieg oder ihr das meint - mich interessiert aber was ihr denkt.

edit : man meine rechtscheibung ist grottig ...
private Nachricht | Beiträge des Benutzers
dani.net
myCSharp.de - Member

Avatar #avatar-2269.gif


Dabei seit:
Beiträge: 175
Herkunft: Wil SG / Schweiz

beantworten | zitieren | melden

Die Brandmarkung ist nur der eine Teil deiner Tierfeindlichkeit, viel schlimmer ist, dass du ihnen keine eigene Persönlichkeit anerkennst :-) Die Identität darf keinesfalls nur über äussere Attribute definiert sein, das wäre äusserst unstrukturiert und liesse enormen Spielram für Unklarheiten.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Moooitic,

die Identität ist gerade etwas ganz anders als eine Eigenschaft des Objekts. Auch wenn man technisch gesehen meist nicht umhin kommt, auch eine Id als Eigenschaft in das Objekt zu packen, hat die Identität des Objekts den gleichen eigenständigen Rang, wie Zustand und Verhalten. Zustand, Verhalten und Identität sind die Dreieinigkeit der Objektorientierung. Siehe auch das, was ich in Schwächen der C#-Sprache an den Eisbären geschrieben habe. Wenn ich es mir Recht überlege, gehe ich in Kopie ohne IClonable ausführlicher auf das Thema Dreieinigkeit ein.

herbivore
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

Hihi :-)

Em ja das Problem das dahinter steht ist aber wohl eins das nur mit einer gott und die welt diskusion Gelöst werden kann...

Mir persönlih kann nimand beweisen das b nicht a ist wenn a und b einfach VOLLKOMMEN identisch sind :-)
Nehmen wir an die kuh denkt wie die andere kuh - sieht aus wie sie und auch sonst ist sie wie die andere - dann ist sie noch nicht anders ?
Wer kann mir sagen das dann nicht 2 mal die gleiche kuh da steht ?

Und die OO ist doch ein relativ Weltnahes konzept - warum sollte die identität dann anders sein ?

Zur laufzeit weiß ich ja wieviele kriterien ich zur unterscheindung keinne - und alles was dann gleich ist ist auch glech.

//EDIT sorry post war mal wieder zu spät - ich lese :-)
private Nachricht | Beiträge des Benutzers
dani.net
myCSharp.de - Member

Avatar #avatar-2269.gif


Dabei seit:
Beiträge: 175
Herkunft: Wil SG / Schweiz

beantworten | zitieren | melden

Überleg dir doch mal was unter "Gleichheit" bei Kühen zu verstehen ist. Wenn du sagst, Kuh a ist dieselbe wie Kuh b, wieso stehen denn da zwei Kühe und fressen dazu noch unterschiedliches Gras... da kann man doch nicht von Gleichheit sprechen, höchstens von Ähnlichkeit
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Moooitic,

das zwei Kühe so vollkommen gleich sind, ist schwer vorzustellen. Aber nehmen wir was einfacheres: Teebecher. Wenn du zwei Teebecher hast, die vollkommen gleich und nicht zu unterscheiden sind, so hast du doch trotzdem zwei Teebecher. Sie sind damit nicht identisch, obwohl die vollkommen gleich sind.

herbivore
private Nachricht | Beiträge des Benutzers
Moooitic
myCSharp.de - Member



Dabei seit:
Beiträge: 15

Themenstarter:

beantworten | zitieren | melden

Also ich hab einiges von den Beiträgen gelesen.
Das Problem ist das Wir ja grad daruber reden ob referenztypen eine daseinsberechtigung haben.

Das problem ist folgendes wenn ich kuh a und kuh b habe und alles an ihnen ist gleich.
Dann ist die Identität das merkmal das mir zur unterscheidung der beiden dient.
Es ist ein hashwert des heap der sozusagen einmalig und fest ist.

Er hat jedoch keinen bezug zum objekt selber - das heist das ich darüber nichts weiter als den von gott ( oder meim pc oder meiner vm) gegebenen Gefängnisstrafcode erhalte.

Ich versuche es andersrum:
Wenn jemand denkt wie ihr, und alles an ihm ist wie auch bei euch dann ist er in dem moment der zeit genau die selbe person wie ihr - er steht an der selben stelle (x = 0 , y = 2) wer kann mir nun sagen das ihr nicht gleich seit.

Imo ist die identität ein gedanke der daher kommt das wir alle seit jahrhunderten an seelen und daran glauben das nimand ich ist. Das mag für uns auch gelten weil niemand von uns an x und y stehen kann wenn da ein anderer steht.
Aber es ist nicht gesagt das es daher nicht geht.

das ist dann doch einfach im objekt zu realisiren so das es keine doppelten gbt - es kann kein x , y gleich sein beim Mensch-object - simpel so halt ich sie ggf auseinander.

Nchmal anders :
Man stelle sich vor das object Mensch a b steht an x , y gleich - alle seine eigenschaften sind gleich ALLES ist gleich und doch sind sie nicht glech da Id(a) != Id(b) ... macht das echt mehr Sinn ?

Wie gesagt ich denke das liegt alles an einem Heap-Computer-Konzept das es ref gibt. ( nochmal Laufzeit und speicher als stichwort.)
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Moooitic,

kurz gesagt: zwischen Gleichheit und Identität zu unterscheiden macht Sinn.

Es ist natürlich so, dass zwei Dinge die identisch sind immer auch zwangsweise gleich sind. Andersherum gilt das aber gerade nicht automatisch.

Mit Heap hat das Ganze gar nichts zu tun.

herbivore
private Nachricht | Beiträge des Benutzers