C++ nach C#?



  • Ich habe mich entschlossen C# zu lernen. Die Sprache sieht ganz interessant aus und ich möchte meinen Horizont etwas erweitern. (Falls das eine schlechte Idee ist, weist mich gerne darauf hin.)

    Da ich unter Archlinux arbeite habe ich mir mono und die MonoDevelop IDE runtergeladen. Die IDE sieht klasse aus.

    Nun zu meiner Frage: Da ich praktisch ausschließlich mit C++ programmiert habe, sehe ich mich als einen C++ -> C# Umsteiger. Gibt es allgemeine Tipps für solche Umsteiger, bezüglich der Standard-Bibliothek, der Idiome o.ä.? Falls ihr ebenfalls solche Umsteiger wart, was sind euch für Denkfehler unterlaufen die man vermeiden kann?

    Wie sieht es mit der Struktur der Programme aus? In C++ gibt es Übersetzungseinheiten die zu Objektdateien kompiliert werden, welche vom Linker in eine Ausführbare Datei gelinkt werden. Werden in C# die einzelnen Source-Dateien in Bytecode einer VM kompiliert?

    Mir ist klar das man das alles im Netz recherchieren kann, ich suche aber nach Erklärungen die für einen C++-Programmierer am einfachsten und missverständniss-freiesten zu verstehen sind.

    PS: Ich denke nicht das ich ein Buch brauchen werde. Ist das naiv, oder kann man sich tatsächlich problemlos alles im Netz aneignen?



  • Arcoth schrieb:

    Nun zu meiner Frage: Da ich praktisch ausschließlich mit C++ programmiert habe, sehe ich mich als einen C++ -> C# Umsteiger. Gibt es allgemeine Tipps für solche Umsteiger, bezüglich der Standard-Bibliothek, der Idiome o.ä.? Falls ihr ebenfalls solche Umsteiger wart, was sind euch für Denkfehler unterlaufen die man vermeiden kann?

    Also als ich vor langem umgestiegen bin, würde ich folgendes als am Auffallendsten bezeichnen:

    • Größere Unterschiede zwischen class und struct, kurz gesagt sind Klassen Referenztypen und Klassen Valuetypen
    • Keine globalen Methoden, alles muss in einer Klasse sein
    • Größe der Integraltypen ist vordefiniert
    • Dank .NET gibt es viel mehr Funktionen die man ohne externe libs nutzen kann, bedeutet aber natürlich auch eine Umgewöhnung
    • Keine Templates, dafür Generics
    • Garbagecollector (was nicht heißt dass man sich um Speicher keine Gedanken mehr machen sollte)

    Hier noch ein paar mehr Unterschiede: MSDN - C# für C++-Entwickler

    Arcoth schrieb:

    Wie sieht es mit der Struktur der Programme aus? In C++ gibt es Übersetzungseinheiten die zu Objektdateien kompiliert werden, welche vom Linker in eine Ausführbare Datei gelinkt werden. Werden in C# die einzelnen Source-Dateien in Bytecode einer VM kompiliert?

    Naja, in C# gibt es keine Header und insofern braucht man auch keine Vorwärtsdeklarationen.
    In C# wird alles in einen Zwischencode übersetzt (MSIL) und dann zu einer exe zusammengesetzt. Da es nur Bytecode ist, lässt es sich bis auf die Kommentare 1:1 zurückübersetzen.
    Wie genau die Übersetzung läuft weiß ich auch nicht, wobei ich mir vorstellen könnte dass in C# die Sources abhängiger voneinander sind, eben weil es keine Header gibt.

    Arcoth schrieb:

    PS: Ich denke nicht das ich ein Buch brauchen werde. Ist das naiv, oder kann man sich tatsächlich problemlos alles im Netz aneignen?

    Da ich C# als deutlich einfacher als C++ bezeichnen würde und man im Netz wirklich viel findet, würde ich sagen dass es ohne Buch auch geht. Ich zumindest hatte nie eins und komme damit ganz gut klar.



  • Bücher würde ich immer empfehlen!

    http://openbook.galileo-press.de/visual_csharp_2012/



  • Ich weiß nicht, ob es dir wirklich Spass machen wird. Dafür braucht man die entsprechenden Projekte. Ich habe mir C# so ziemlich gleich angeschaut, als es rausgekommen ist. Aber so wirklich intensiv habe ich mich damit erst beschäftigt, als ich in einer Firma angefangen habe, die Enterprise Anwendungen geschrieben hat. Das war wirklich toll. Auch die Projekte und das ganze Umfeld war für mich neu, deswegen fand ich das alles interessant.
    Aber ich könnte mir gut vorstellen, dass die Sprache allein für dich ohne die entsprechenden Projekte nicht so spannend sein wird.
    Die Sprache kann man ohne Bücher schon verstehen. Aber es gibt da mittlerweile sehr viele Best Practices im .NET Umfeld. Ich hab mich jetzt schon seit paar Jahren nicht mehr damit beschäftigt und vieles ist an mir vorbeigegangen. Wenn du z.B. GUI machen willst, geht ohne MVVM und entsprechende Frameworks (und noch paar dutzend Buzz Words) nichts mehr. Wenn du Datenbanken machen willst, sind mittlerweile auch ORM Frameworks im Standard dabei, die man kennen sollte. Im Multithreading Bereich genauso. Aber wenn du jetzt z.B. weder GUI noch Datenbanken machen willst, dann sind ein Großteil der Vorteile, die .NET bietet für dich von vornherein uninteressant.



  • Arcoth schrieb:

    Ich habe mich entschlossen C# zu lernen.

    👍
    Praktische Sprache, schöne Bibliothek.

    Ich hatte auch einen C++-Hintergrund, als ich mit C# angefangen habe. Hier ein paar Sachen, die mir so auf Anhieb einfallen (wenn ich dabei mit unbekannten Begriffen um mich werfe, verstehe das als Aufforderung, sie nachzulesen 🙂 ). Nicht alles ist C#-spezifisch, manches bezieht sich auch auf Eigenheiten von Framework oder Runtime, die einem C++-Programmierer evtl. unvertraut sind.

    • Wenn du die Übersichtlichkeit von Headerdateien vermißt: Ctrl+K,O in Visual Studio klappt alle Implementationsdetails ein. Einen ähnlichen Shortcut hat Monodevelop bestimmt auch.
    • der GC ist kein Implementationsdetail. Man muß sich immer darüber bewußt werden, welche Art Ressourcen man gerade verwaltet und ggf. IDisposable und using verwenden.

    Falls du wie so viele C++-Verfechter versucht bist, das GC/ IDisposable -Modell für prinzipiell bescheuert und RAII für die universelle Lösung zu erklären, oder wenn du mehr über die Hintergründe der Design-Entscheidungen wissen willst, dann ist [1] eine Leseempfehlung für dich.

    • Lerne LINQ und bekomme ein Gefühl dafür, was lazy evaluation in der Praxis bedeutet, und welchen Unterschied es macht, ob man Queries ( IEnumerable<> ) oder Datenstrukturen herumreicht.
    • C# hat relativ viel Syntaxunterstützung für monadische Typen. Explizit unterstützt werden etwa Nullable<> ( ? -Typsuffix und Operatorüberladungen), IEnumerable<> ( foreach , yield return / yield break ) und Task<> ( async / await ). Eine Kopplung von Bibliothekstypen und Sprachkonstrukten ist in C++ ja verpönt ( typeid() ist auch das einzige Beispiel, was mir einfällt). Aber manchmal lohnt es sich halt doch 🙂

    Die LINQ comprehension syntax wird zwar meist mit IEnumerable<> verwendet, kann aber auf beliebige Monaden angewandt werden (z.B. IObservable<> , Expression<IEnumerable<>> ). Lesetipp: [3].

    • Properties und Events sehen aus wie Felddefinitionen, sind aber semantisch zusammengefaßte Methodenpaare ( get und set bzw. add und remove ). Wenn du die Methoden nicht explizit angibst, wird implizit ein Feld desselben Typs angelegt, auf das die Methoden dann zugreifen. Bei Properties kann man das Feld nicht direkt ansprechen, bei Events schon (natürlich nur innerhalb der Klasse). Die Multicast-Fähigkeit (also daß du ein Delegate mit += an mehrere Funktionen binden kannst) ist eine Eigenschaft der Delegate-Typen und kein Spezifikum von Events. All das hat mich zu Anfang ziemlich verwirrt.
    • Unschätzbar wertvoll ist, daß du das Framework im Quelltext einsehen kannst [2], und daß es anders als STL oder Boost sehr lesbarer Code ist. Außerdem kannst du kompilierte Assemblies mit ILSpy dekompilieren. Auch deine eigenen; das ist hilfreich, wenn du verstehen willst, was die syntaktischen Erleichterungen des Compilers ( using , foreach , Iteratoren ( yield return / yield break ), LINQ comprehension syntax, Expression LINQ, async / await ) genau machen.
    • Generics sind toll. Ich habe auch meinen Spaß mit TMP gehabt, und natürlich ist es faszinierend, was man mit Templates anstellen kann. Aber generische Funktionen/Klassen werden bereits kompiliert, bevor sie instanziiert werden, weshalb Fehlermeldungen auch dort auftreten, wo sie hingehören (nämlich beim Aufrufer). Außerdem kann man Typbeschränkungen für Argumente angeben ( class DisposableGuard<T> where T : IDisposable ), und generische Interfaces und Delegates können kovariante und kontravariante Typargumente haben. Und du kannst generische Typen und Methoden zur Laufzeit mit neuen Typargumenten instanziieren. Auch generische virtuelle Methoden sind erlaubt.
    • In C++ ist es ja üblich, daß man immutable views auf (möglicherweise) veränderliche Objekte herumgibt (d.h. const T& ). Ein vergleichbares Sprachmittel gibt es in C# nicht, aber es ist üblich, möglichst viele eigene Datentypen immutable zu machen, d.h. die Felder als readonly zu deklarieren und im Konstruktor zu initialisieren. Vorteile sind dieselben wie in C++.
    • struct -Typen sollten unveränderlich sein. Sie müssen es nicht, aber die Wertsemantik hat für veränderliche struct s ververschiedene nichtoffensichtliche Konsequenzen, also solltest du genau wissen, was du tust.

    Überhaupt ist aus der Tatsache, daß struct Wertsemantik und class Referenzsemantik hat, nicht abzuleiten, daß du struct benutzen sollst, wenn du Wertsemantik willst. struct ist in der Handhabung nicht mit Werttypen in C++ vergleichbar, insbesondere weil es keine Möglichkeit gibt, eine Referenz auf einen struct herumzugeben (Ausnahme: ref / out -Parameter beim Aufruf einer Methode). Wenn ComplexType ein struct ist, kannst du also das hier nicht machen:

    var myList = new List<ComplexType>(...);
    myList[j].SomeProperty = 12;
    

    Der Grund ist, daß der Indexer eine Kopie des ComplexType zurückgeben muß. In diesem Fall macht dich der Compiler drauf aufmerksam, aber es gibt andere Fälle, wo er das nicht kann und du nur unerwartetes Verhalten bekommst.

    Derartige Fallstricke vermeidet man, indem man für veränderliche Typen immer class nimmt. Und wenn du dann Equals() , GetHashCode() und operator == / operator != überschreibst, habt dein Typ auch Wertsemantik. Allerdings ist ein veränderlicher Typ mit Wertsemantik immer problematisch; deshalb gibt dir z.B. std::map<> immer nur eine const -Referenz auf den Key.

    Wenn du einen unveränderlichen Referenztypen mit Wertsemantik willst, kannst du Tuple<> benutzen oder davon erben, um dir das manuelle Implementieren der o.g. Methoden zu ersparen.

    • Hast du schonmal das Visitor-Pattern gebraucht? Dabei macht man ja einen Slot in der VMT seiner Klassenhierarchie für Drittcode zugänglich, um effizientes Double-Dispatching zu ermöglichen. Kam es dir auch sehr unintuitiv und umständlich vor? Dann schau dir dynamic an, damit bekommst du overload resolution zur Laufzeit.
    • Ein netter Seiteneffekt der Ausführung in der CLR ist, daß du zur Laufzeit Code generieren kannst, z.B. mit Reflection.Emit oder mit expression trees. Natürlich ist das kein adäquates Mittel zur Lösung von Allerweltsproblemen (und es ist auch auf einigen mobilen Plattformen nicht verfügbar), aber es ist unbestreitbar nützlich, z.B. für Projekte wie [4].

    [1] http://blogs.msdn.com/b/brada/archive/2005/02/11/371015.aspx
    [2] http://referencesource.microsoft.com/
    [3] http://mikehadlow.blogspot.de/2011/01/monads-in-c1-introduction.html
    [4] http://www.mono-project.com/docs/tools+libraries/tools/repl/



  • DarkShadow44 schrieb:

    ...
    [*]Garbagecollector (was nicht heißt dass man sich um Speicher keine Gedanken mehr machen sollte)...

    Wie war, z.Z. bin ich gerade mit Unterstützungsleistung beauftragt, um einen oder mehrere Speicherfresser in einer C# Anwendung zu finden.

    Es scheint in der Tat tatsächlich Umsteiger zu geben, die der Meinung sind, nun brauchen sie das, was sie vorher (u.a auch durch c++) gelernt haben, nicht mehr zu beachten, weil C# "ja alles von alleine kann". 🙂



  • Wird einem ja auch immer so "verkauft", das GC-Sprachen den Programmierer entlasten und vor Speicherfehlern bewahren! War ja auch schon in den 1990er Jahren mit Java so. Und einen anderen Grund für einen GC kann ich ehrlich gesagt auch nicht erkennen?



  • Artchi schrieb:

    Wird einem ja auch immer so "verkauft", das GC-Sprachen den Programmierer entlasten und vor Speicherfehlern bewahren! War ja auch schon in den 1990er Jahren mit Java so. Und einen anderen Grund für einen GC kann ich ehrlich gesagt auch nicht erkennen?

    Ist bei Datenbanken ja auch nicht anders, da wird den Führungskräften erzählt, das die tolle Datenbank das alles kann was benötigt wird. Und die gucken dann auf einmal dumm aus der Wäsche, wenn man denen dann erzählt, das man der teuer eingekauften Datenbank auch erst einmal beibringen muss, was sie können soll.



  • Es gibt schon einige Unterschiede zwischen C++ und C#. Das wesentliche Merkmal von C# ist, dass alles komplett
    objektorientiert auf Klassen aufgebaut ist und man sich strikt daran zu halten hat. Vorteil ist die sehr umfangreiche
    Funktionsbibliothek von .NET.

    Man kann den Einstieg sehr gut ohne Bücher oder Tutorials beginnen oder einfach dieses hier Buch lesen
    https://www.c-plusplus.net/forum/313049

    Ein wenig Umdenken ist schon erforderlich. Und auf Hindernisse stösst man auch, weil C++ doch nicht strikt
    objektorientiert ist.

    Beginne erst den eigenen Einstieg mit Testanwendungen und nicht gleich mit der Konvertierung vorhandener Projekte.



  • berniebutt schrieb:

    Es gibt schon einige Unterschiede zwischen C++ und C#. Das wesentliche Merkmal von C# ist, dass alles komplett
    objektorientiert auf Klassen aufgebaut ist und man sich strikt daran zu halten hat. Vorteil ist die sehr umfangreiche
    Funktionsbibliothek von .NET.

    Vielleicht ist es auch eine Klassenbibliothek, man weiß es nicht.

    Wenn Leute so etwas von wegen "objektorientiert" blubbern, frage ich mich, ob sie vielleicht etwas ganz anderes damit meinen. Die wesentlichen Unterschiede zu C++ sind der Garbage Collector und das opt-in unsafe . Von diesen Unterschieden überwältigt fällt der Blick dann auf ein unwichtiges und gleichzeitig allgegenwärtiges Detail: Funktionen können nur in class -Blöcken stehen. Was für eine Revolution! Jede Entwicklungsumgebung kann neue Klassen anlegen, da macht sich die Arbeit fast wie von selbst. Hmm, wo muss diese Funktion hin? Ach natürlich, in die erstbeste Klasse! In C++ kann man Funktionen fast überall hinschreiben. Da muss man nachdenken. Nachdenken ist doch gar nicht objektorientiert!



  • TyRoXx schrieb:

    Von diesen Unterschieden überwältigt fällt der Blick dann auf ein unwichtiges und gleichzeitig allgegenwärtiges Detail: Funktionen können nur in class -Blöcken stehen. Was für eine Revolution!

    Zumal C# 6 using static einführt, um den syntaktischen Ballast zu beseitigen, so daß man fortan Cos() statt Math.Cos() schreiben kann.

    Ich höre schon den Aufschrei, das sei doch dann nicht mehr objektorientiert 🤡



  • @Arcoth
    Wichtinge Unterschiede gibt es mMn. einige was das Thema Finalisierung angeht. Bzw. Stolpersteine. Bzw. Dinge die man einfach wissen sollte.
    z.B.:
    * Der "Destruktor" (C# nenn das dummerweise so) kann aufgerufen werden während noch Memberfunktionen "auf" dem Objekts laufen. Und zwar wenn die Ausführung der Memberfunktionen an einem Punkt angekommen ist, wo "this" danach nicht mehr benötigt wird. Siehe GC.KeepAlive .
    * Der "Destruktor" und die Dispose Methode können also auch gleichzeitig laufen.
    * Die Dispose Methode kann mehrfach laufen, u.U. auch in verschiedenen Threads.
    * Nachdem Dispose aufgerufen wurde können natürlich noch weiterhin andere Memberfunktionen aufgerufen werden.
    * Man kann Objekte im "Destruktor" "resurrecten" indem man in irgend einem anderen Objekt wieder eine Referenz auf das bereits "unreachable" gewordene Objekt einträgt. Wenn man das macht muss man es allerdings auch dem GC mitteilen ( GC.ReRegisterForFinalize ). Und "normale" Weak-References glauben danach dass das Objekt immer noch "nicht mehr da" ist - man muss speziell trackResurrection=true übergeben wenn man solche wiederauferstandenen Objekte auch über die Weak-References wieder erreichen können möchte.
    * "Destruktoren" von Basisklassen werden automatisch aufgerufen, bei Dispose muss man dies allerdings selbst erledigen.

    Und generell sollte man nicht glauben was öfters im Netz zu lesen bekommt, nämlich dass man in C# deterministische Finalisierung (über IDisposable ) kaum jemals wirklich braucht, und es daher damit "nicht übertreiben sollte". Was totaler Humbug ist. Man sollte viel mehr sehr genau darauf achten und es überall dort implementieren wo es eben nötig ist.
    Sonst bekommt man ganz schnell ein Programm das schlecht skaliert, oder einfach mal w/o gibt wenn es zu lange läuft ohne neu gestartet zu werden. Kenn man ja auch von einigen Java-Anwendungen.

    Ein Pattern das mir beim C# Programmieren sehr geholfen hat, auf das mal als C++ Programmierer schnell kommt, als C++ unkundiger C# Programmierer aber vielleicht nicht, sind "RAII Hilfsklassen". Also Klassen die IDisposable implementieren, die man dann in einem using Block verwenden kann um irgendwas beim Scope-Exit zu machen.



  • Ist nicht alles ohne RAII und mit GC verpönt? Ich meine aufpassen muss man auch in C++. Aber wenn es reicht in Java und auch C# aufzupassen, warum werden sie dann schlechter gemacht als sie vielleicht sind? Ich mache C++ und Java und mir ist noch NIE da irgendwie die GC oder anderes komischen Sachen in die Quere gekommen und schon gar nicht hat mir RAII gefehlt.

    Was theoretisch alles passieren kann ist mir in der täglichen Praxis so ziemlich egal, außer es geht um Sicherheit.



  • Man vermisst selten wirklich was, wenn man sich an eine Programiersprache gewöhnt hat und damit arbeitet. Hat mich schon immer genervt, dass man in Java keine Strings mit == vergleich kann, und zig andere Sachen. Aber als ich eine Weile Java programmieren musste, war mir das auch völlig egal, ich war im Projekt drin und hab nichts vermisst.



  • Na, was wird denn immer hier erzählt, dass man in Java irgendwann in Probleme rennt, weil man eben kein RAII hat und sich auf die Willkür eines GC verlassen muss. Dann wird noch propagiert, dass man die ganzen C++-Fehler, die der C++-Compiler anprangert, auch in Java hat, aber diese sind dort keine Fehler, weil nicht so hart geprüft würde. Diese Fehler fliegen einen dann in Java später um die Ohren und in C++ werden die gleich zu Anfang, durch die Fehlermeldungen, gefunden.

    Dieser fehlende GC und das RAII hat mich dazu bewogen mein Projekt in C++ neu anzufangen, weil ich den Profis hier vertraute. Ich dachte irgendwann kommt die Keule in Java, weil es eben kein C++ mit so starken Prüfungen ist.

    Ich persönlich hatte nie Probleme mit Java und auch C# habe ich ausprobiert. Vom Zeitfaktor bin ich in Java fünf mal so schnell fertig mit dem Code, da komme ich sehr schnell voran und die IDE unterstützt mich da optimal.



  • Meine Einschätzung ist, dass man mit Java/C# bei kleinen Projekten fast immer schneller ist als mit C++, und bei größeren Projekten sich das dann ausgleicht und Richtung C++ verschiebt. Kommt natürlich auch auf die Projekte drauf an. Ich hab früher Enterprise Software in C# geschrieben, da gibts einfach sehr viele Probleme, für die die Sprache und das Framework schon was haben. Da kann man z.B. sehr viel mit Refection erschlagen, z.B. ORM und Data Binding. Kommt in Enterprise Anwendungen ständig vor, deswegen ist man da produktiv. Dann braucht man natürlich ständig XML, hat man sogar auch in die Sprache integriert, mit Linq to XML. Webservices usw. wird alles problemlos unterstützt.
    Jetzt arbeite ich an einem großen C++ Projekt und brauche einfach nicht so viel davon. Datenbanken spielen bei uns zwar auch eine Rolle, aber anders, da hat man mit ORM kaum was gewonnen, Stammdaten und irgendwelche Eingabemasken mit Data Binding usw. kommt praktisch nicht vor. Ich bin in dem Projekt subjektiv auf das Projekt bezogen genauso produktiv wie früher mit C#, ich vermisse die Sprache und das Framework also auch nicht. Und wenn wir mal GUI machen, dann ist die meist sehr komplex, einfache Eingabemasken sind extrem selten und irrelevant, und da komm ich mit Qt auch wunderbar zurecht. Da kommen die Features von C++, z.B. RAII und gute Unterstützung für Value Typen stärker zur Geltung. Ich finds sehr angenehm, mit richtigen Value Typen zu arbeiten. Und man kann die Klassen leichter so aufbauen, dass der Compiler falsche Benutzung verhindert. Und das ist bei einem Projekt mit zig Millionen Zeilen Code und dutzenden Entwicklern schon wichtig. Und unsere Architektur ist teilweise sehr komplex und unüberschaubar. An einem "Prozess" oder Workflow können mehrere Prozesse, meist teilweise auf unterschiedlichen Rechnern, beteiligt sein, dann gibts an zig Stellen Customizations, wo irgendwelche Scripte ausgeführt werden, die wir nicht unbedingt im Griff haben, Plugins die innerhalb anderer System (z.B. CAD) laufen, Fremdsoftware usw... RAII heißt dann z.B. wir haben ein Handle auf ein Objekt, dass in einem anderen Prozess auf einem anderen Rechner lebt. Und dieses Objekt könnte wiederum eine Referenz auf ein Objekt (z.B. ein Callback) in unserem Prozess haben. Da ist es sehr wichtig, dass es alles stabil, in der richtigen Reihenfolge und zeitnah freigegeben wird, und nicht dass der GC irgendwann mal irgendwas in zufälliger Reihenfolge freigibt.



  • RAIIGCFrage schrieb:

    Was theoretisch alles passieren kann ist mir in der täglichen Praxis so ziemlich egal, außer es geht um Sicherheit.

    In der Praxis hast du dummerweise viele Programmierer die es einfach nicht schert aufzupassen. Bzw. die einfach doof sind. Oder beides.
    Deswegen gibt es in der Praxis auch so viele Java und C# Projekte die Probleme mit der Resourcenverwaltung haben. Die man alle paar Tage oder gar Stunden neu starten muss weil sie sonst anfangen Zahnräder zu spucken. Oder die einen megafetten DB-Server brauchen, weil sie meinen DB-Connections einfach nicht freigeben zu müssen ("macht eh der GC für mich").

    Dummerweise machen diese Programmierer in der Praxis mit C++ genau so viele Fehler. Bloss eben andere. Nämliche oft welche wo dann gleich das ganze Programm abschmiert.

    Daher sind Sprachen wie Java oder C# im enterprisigen Bereich beliebt. Weil's halt besser ist wenn man "nur" Performance-Probleme hat die man mit nem periodischen Restart oder nem dickeren DB-Server beheben kann - als wenn das Programm einfach abkackt.
    (OK, natürlich nicht nur daher, aber es ist sicher einer der Gründe.)



  • Ist das Chauffeur-Wissen? Wenn nein, dann nenne mir ein paar C# und/oder Java-Anwendungen bei denen dies so ist. Eigentlich müsste es ja viel mehr als ein paar Anwendungen sein um solch eine Behauptung aufstellen zu können.

    Einen dickeren Rechner hinzustellen, kann weit aus sparsamer sein, als längere Entwicklungszeiten, oder noch schlimmer Fachkräftemangel weil die Sprache zu komplex ist.



  • QuellenBitte schrieb:

    Chauffeur-Wissen

    Supi Argument.

    QuellenBitte schrieb:

    Fachkräftemangel

    Geh weiter extrem wichtige PowerPoint-Präsentationen malen.



  • hustbaer schrieb:

    RAIIGCFrage schrieb:

    Was theoretisch alles passieren kann ist mir in der täglichen Praxis so ziemlich egal, außer es geht um Sicherheit.

    In der Praxis hast du dummerweise viele Programmierer die es einfach nicht schert aufzupassen. Bzw. die einfach doof sind. Oder beides.

    Das kann ich zwar unterschreiben (Gerade das von dir weiter unten angesprochene nicht-schließen von DB-Connections wird zum Teil selbst in Fachliteratur gerne gemacht), aber ich kenne aus der Praxis bislang keinen einzigen Fall bei dem...

    hustbaer schrieb:

    Deswegen gibt es in der Praxis auch so viele Java und C# Projekte die Probleme mit der Resourcenverwaltung haben. Die man alle paar Tage oder gar Stunden neu starten muss weil sie sonst anfangen Zahnräder zu spucken. Oder die einen megafetten DB-Server brauchen, weil sie meinen DB-Connections einfach nicht freigeben zu müssen ("macht eh der GC für mich").

    ...dies nötig wäre. Zumindest sind mir solche Fälle eigentlich das letzte mal vor etwa 10 Jahren vor die Flinte gekommen.

    hustbaer schrieb:

    Daher sind Sprachen wie Java oder C# im enterprisigen Bereich beliebt. Weil's halt besser ist wenn man "nur" Performance-Probleme hat die man mit nem periodischen Restart oder nem dickeren DB-Server beheben kann - als wenn das Programm einfach abkackt...

    Nach meiner Erfahrung sind es ganz andere Argumente für C# im Enterprise-Bereich. Zwar braucht eine C#/Java-Anwendung (auch bei guter Programmierung) mehr Ressourcen als eine C++-Anwendung gleicher Art und Qualität, entscheidend ist aber die Entwicklungszeit (und diese ist nach meiner Erfahrung, im Gegensatz zu Mechanics Erfahrung - in jeder Projektgröße stark bemerkbar).

    Es ist billiger einen etwas höher gerüsteten PC hinzustellen (vorwiegend geht es um etwas mehr RAM, und vielleicht ein klein wenig schnelleren Prozessor), als eine längere Entwicklungszeit zu bezahlen.

    hustbaer schrieb:

    (OK, natürlich nicht nur daher, aber es ist sicher einer der Gründe.)

    Keiner der Gründe die ich als wirklich relevant in der Praxis bemerkt hätte.

    P.S: Davon abgesehen kann es für die Performance sogar manchmal besser sein eine Connection nicht gleich frei zu geben (und Connectionpooling zu betreiben). Das ist aber abhängig davon wie häufig man Connections erzeugen muss.


Anmelden zum Antworten