Frage

Ich entwickle und eine große (500k + LOC) WinForms halten in C # 2.0 geschrieben App. Es ist Multi-User und wird zur Zeit über 15 Maschinen im Einsatz auf. Die Entwicklung des Systems ist noch nicht abgeschlossen (kann als eine perpetual beta gedacht werden), und es gibt sehr wenig Benutzer vor möglicher neuer Bugs getan zu schützen, die in einer wöchentlichen Build eingeführt werden könnten.

Aus diesem Grunde unter anderem habe ich finde ich sehr darauf angewiesen, immer edit-und-weiter im Debugger. Es hilft nicht nur mit Bug-Jagd und Bug-Fixing, aber in einigen Fällen mit dem laufenden Entwicklung auch. Ich finde es äußerst wertvoll der Lage sein, neu geschriebenen Code auszuführen aus im Rahmen einer laufenden Anwendung - es gibt keine Notwendigkeit, neu zu kompilieren ist und einen bestimmten Einstiegspunkt zu den neuen Code hinzufügen (mit Dummy-Menüoptionen hinzufügen, Knöpfe, etc die App und erinnern sie vor der nächsten Produktion bauen zu entfernen.) - alles versucht und ohne Unterbrechung des Prozesses in Echtzeit getestet werden können

Ich halte edit-and-continue in einem so hohem Ansehen, dass ich aktiv Code schreibt damit voll kompatibel sein. Zum Beispiel habe ich vermeiden:

  • Anonyme Methoden und Inline-Teilnehmer (es sei denn, völlig unmöglich zu umschreiben)
  • Allgemeine Verfahren (außer in einem stabilen, unveränderlichen Utility-Code)
  • Targeting Projekte 'Any CPU' (das heißt nie in 64-Bit-Ausführung)
  • Initialisieren Felder an der Stelle der Erklärung (Initialisierung an den Konstruktor bewegt wird)
  • Schreiben enumerator Blöcke, die Verwendung yield (außer im Utility-Code)

Nun, sie ist voll und ganz bewusst, dass das neue Sprachfeature in C # 3 und 4 sind weitgehend unvereinbar mit edit-and-Continue (Lambda-Ausdrücke, LINQ, etc). Dies ist einer der Gründe, warum ich das Projekt bewegt sich auf eine neuere Version des Rahmen widerstanden haben.

Meine Frage ist, ob es gute Praxis ist es, diese fortgeschrittenen Konstrukte für Code zu vermeiden, verwenden, das ist sehr, sehr einfach zu debuggen? Gibt es Legitimität in dieser Art der Entwicklung, oder ist es eine Verschwendung? Ebenso wichtig ist, führen Sie einen dieser Konstrukte (Lambda-Ausdrücke, anonyme Methoden, etc.) incur Performance / Speicher-Gemeinkosten, die gut geschrieben, edit-and-Continue-kompatiblen Code könnte vermieden werden? ... oder tun das Innenleben des C # Compiler so fortschrittliche Konstrukte schneller als von Hand geschrieben, ‚erweiterte‘ Code?

machen
War es hilfreich?

Lösung

Ohne an Klang banal zu wollen - es ist eine gute Übung, um Schreibeinheit / Integrationstests statt verlassen Bearbeiten-Weiter.

Auf diese Weise verbrauchen Sie sich die Mühe einmal, und jede andere Zeit ist ‚frei‘ ...

Jetzt bin darauf hindeutet, Sie mir nicht nachträglich Schreibeinheiten für die gesamten Code; vielmehr müssen jedes Mal, wenn Sie einen Fehler beheben, starten Sie durch einen Test (oder häufiger mehrere Tests) zu schreiben, dass das Update beweist.

Wie @ Dave Swersky erwähnt in den Kommentaren, Buch Mchael Federn, Effektives Arbeiten mit Legacy- Code eine gute Ressource ist (es Vermächtnis 5 Minuten, nachdem Sie es geschrieben, nicht wahr?)

So Ja, ich denke, es ist ein Fehler, neue C # Konstrukte für so dass für die Bearbeitung zu vermeiden und fortzusetzen; Aber ich denke auch ein Fehler, es ist neue Konstrukte zu umarmen, nur um von ihm, und vor allem, wenn sie härter führen, um Code zu verstehen.

Andere Tipps

Ich liebe ‚Bearbeiten und Fortfahren‘. Ich finde es ist ein großer Enabler für interaktive Entwicklung / Debugging und ich es finden ziemlich ärgerlich, wenn es nicht funktioniert.

Wenn ‚Bearbeiten und Fortfahren‘ unterstützt Ihre Entwicklungsmethodik dann mit allen Mitteln Entscheidungen zu treffen, um es zu erleichtern, unter Berücksichtigung der Wert dessen, was Sie aufgeben.

Einer meiner Haustier ärgert ist, dass die Bearbeitung etwas in einer Funktion mit Lambda-Ausdrücke Pausen ‚Bearbeiten und Fortfahren‘. Wenn ich es genug stolpern ich den Lambda-Ausdruck schreiben kann. Ich bin auf dem Zaun mit Lambda-Ausdrücke. Ich kann mit ihnen ein paar Dingen schneller tun, aber sie tun nicht rettet mir Zeit, wenn ich sie später schriftlich am Ende aus.

In meinem Fall vermeiden ich Lambda-Ausdrücke verwenden, wenn ich wirklich nicht brauchen. Wenn sie in die Quere kommen kann ich sie in einer Funktion wickeln, so dass ich kann ‚Bearbeiten und Fortfahren‘ Der Code, der sie verwendet. Wenn sie überflüssig sind, schreibe ich kann sie aus.

Ihr Ansatz muss nicht schwarz und weiß sein.

Wollte diese Dinge klären etwas

  

es ist eine gute Praxis zu vermeiden, dass diese erweiterte Konstrukte für Code, der sehr, sehr einfach zu debuggen?

Bearbeiten und Fortfahren nicht wirklich debuggen, es entwickelt sich. Ich mache diese Unterscheidung, weil die neue C # -Funktionen sehr debug ist. Jede Version der Sprache fügt Debugging-Unterstützung für neue Sprache bietet sie so einfach wie möglich Debug zu machen.

  

alles versucht und in Echtzeit getestet werden kann, ohne den Prozess zu stoppen.

Diese Aussage ist irreführend. Es ist möglich, mit Bearbeiten und Fortfahren einer Änderung behebt ein sehr spezifisches Problem zu überprüfen. Es ist viel schwieriger zu überprüfen, ob die Änderung korrekt ist und nicht bricht eine Vielzahl von anderen Themen. Und zwar, weil bearbeiten und nicht weiter die Binärdateien auf der Festplatte ändern und somit nicht erlaubt für Elemente wie Unit-Tests.

Insgesamt aber ja, ich denke, es ist ein Fehler, neue C # Konstrukte für so dass für die Bearbeitung zu vermeiden und fortzusetzen. Bearbeiten und Fortfahren sind ein großartiges Feature (liebte es wirklich, wenn ich es zuerst in meinen C ++ Tagen begegnet). Aber es Wert als Produktionsserver Helfer nicht für die producitivy Gewinne aus der neuen C # verfügt über IMHO nicht bilden.

  

Meine Frage ist, ob es gute Praxis ist es, diese fortgeschrittenen Konstrukte für Code zu vermeiden, verwenden, das ist sehr, sehr einfach zu debuggen

Ich würde behaupten, dass jedes Mal, wenn Sie sich zwingen Code zu schreiben, ist:

  1. Weniger ausdruck
  2. Längerer
  3. Wiederholte (aus der Vermeidung generische Methoden)
  4. Non-portable (nie Debug- und Test 64bit ??!?!?)

Sie fügen zu Ihrer gesamten Wartungskosten weit mehr als den Verlust des „Bearbeiten und Fortfahren“ Funktionalität im Debugger.

Ich würde den besten Code möglich schreiben, nicht-Code, der eine Funktion Ihrer IDE Arbeit macht.

Zwar gibt es nichts falsch mit Ihrem Ansatz ist, tut es Grenzen Sie auf die Menge an Ausdruckskraft von der IDE verstanden. Ihr Code wird eine Reflexion von seine Fähigkeiten, nicht die Sprache der und damit Ihr Gesamtwert in der Entwicklung Welt ab, weil man sich zurückhalten vom Lernen andere produktivitätssteigernde Techniken. Vermeiden von LINQ für Bearbeiten-and-Continue fühlt sich an wie eine enorme Opportunitätskosten für mich persönlich, aber das Paradoxe ist, dass man mit ihm etwas Erfahrung zu sammeln, bevor Sie auf diese Weise fühlen kann.

Auch, wie in anderen Antworten erwähnt, Komponententests Code entfernt die Notwendigkeit der gesamten Anwendung des ganzen Zeit laufen zu lassen, und damit Ihr Dilemma in einer anderen Art und Weise löst. Wenn Sie nicht der rechten Maustaste in Ihrem IDE und Test nur die drei Zeilen Code, die Sie interessieren, sind Sie schon zu viel Arbeit während der Entwicklung zu tun.

Sie sollten sich wirklich vorstellen Kontinuierliche Integration, die Sie Fehler zu finden und zu beseitigen, bevor die Bereitstellung von Software helfen können. Besonders große Projekte (Ich halte 500k ziemlich groß) brauchen eine Art der Validierung.

http://www.codinghorror.com/ Blog / 2006/02 / Neubetrachtung-edit-and-continue.html

Im Hinblick auf die konkrete Frage: Nicht vermeiden diese Konstrukte und verlassen Sie sich nicht auf Ihr verrückt Debug-Fähigkeiten - Versuchen Sie zu vermeiden Fehler überhaupt (in bereitgestellte Software). Schreiben Unit-Tests statt.

Ich habe auch auf sehr großen permanent Beta Projekten gearbeitet.

Ich habe anonyme Methoden verwendet und Inline-Delegierten einige relativ einfache Bits von Gebrauch einer Logik der Nähe ihrer alleinigen Verwendungsstelle zu halten.

habe ich generische Methoden und Klassen für die Wiederverwendung und Zuverlässigkeit verwendet.

Ich habe in Konstrukteuren initialisiert Klassen als Voll ein Ausmaß wie möglich, Klasseninvarianten zu erhalten und die Möglichkeit von Fehlern durch Objekte in ungültigen Zuständen, verursacht werden.

Ich habe enumerator Blöcke verwendet, um die Menge an Code zu reduzieren benötigte eine Enumerator-Klasse auf ein paar Zeilen zu erstellen.

Alle diese sind nützlich in ein großes schnell verändernden Projekt in einem betriebssicheren Zustand zu halten.

Wenn ich kann nicht edit-und-weiter, ich bearbeiten und wieder von vorn anfangen. Das kostet mich ein paar Sekunden, die meiste Zeit, ein paar Minuten in fiesen Fällen. Es lohnt sich für die Stunden, die größere Fähigkeit zur Vernunft über Code und eine höhere Zuverlässigkeit durch Wiederverwendung spart mir.

Es gibt eine Menge, die ich tun werde, um es einfacher zu machen, Fehler zu finden, aber nicht, wenn es wird es einfacher zu machen, Fehler zu haben.

Sie könnten versuchen, Testentwicklung Driven. Ich fand es sehr nützlich bei allen mit dem Debugger zu vermeiden. Sie starten von einem neuen Test (z Unit-Test), und dann nur Sie das Gerät zu testen führen Sie Ihre Entwicklung zu überprüfen - Sie müssen nicht die gesamte Anwendung müssen die ganze Zeit laufen. Und das bedeutet, die Sie nicht brauchen edit-und-weiter!

Ich weiß, dass TDD das aktuelle Schlagwort ist, aber es funktioniert wirklich für mich. Wenn ich den Debugger verwenden müssen, ich nehme es als persönliches Versagen:)

Unter Berufung auf Bearbeiten und Cont. Geräusche, als ob es auf die Entwicklung neuer Funktionen nur sehr wenig Zeit damit verbracht, geschweige denn Unit-Tests. Das finde ich schlecht, weil Sie wahrscheinlich eine Menge Debugging und Fehlerbehebung am Ende tun, und manchmal Ihre Fehlerbehebung verursachen mehr Fehler, nicht wahr?

Es ist jedoch sehr schwer zu beurteilen, ob Sie sollten oder nicht Sprachfunktionen nutzen oder nicht, denn dies hängt auch von vielen, vielen anderen Faktoren ab: Projekt reqs, Release-Terminen, Teamfähigkeit, Kosten des Code Verwaltbarkeit nach Refactoring, zu nur einige nennen.

Hope, das hilft!

Das Problem, das Sie scheinen zu haben ist:

  

Es dauert zu lange Sie wieder aufbauen App,   starten Sie es wieder nach oben und nach etwas bekommen   von UI arbeiten Sie.

Wie jeder gesagt hat, wird von Unit-Tests helfen, die Häufigkeit reduzieren Sie Ihre Anwendung finden / fix Bugs auf keine UI-Code auszuführen; aber sie haben nicht Hilfe bei Themen wie das Layout der Benutzeroberfläche.

In der Vergangenheit hat ich einen Test-App geschrieben, die schnell die Benutzeroberfläche geladen werden, an dem ich arbeite und füllen es mit Dummy-Daten, um die Zykluszeit zu verringern.

kein UI-Code in andere Klassen Aussortieren, die mit Unit-Tests getestet werden können, ermöglicht es Ihnen, alle C # Konstrukte in diesen Klassen verwenden tun. Dann können Sie einfach die Konstrukte in Gebrauch begrenzen im UI-Code seiner selbst.

Wenn ich schreibe viele Unit-Tests begonnen, meine Verwendung von „edit-and-Continue“ ging, ich, wie es sich kaum von UI-Code verwenden auseinander.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top