C #: Vorteil der expliziten Angabe der "unsicheren" / Compiler-Option

8

Ich verstehe Zeiger und die seltene Notwendigkeit, sie in C # -Code zu verwenden. Meine Frage ist: Was ist der Grund dafür, dass man in einem Codeblock explizit "unsicher" angeben muss? Außerdem, warum muss eine Compiler-Option geändert werden, um "unsicheren" Code zuzulassen?

Bottom Line: Was in der CLR (oder in den Sprachspezifikationen) dazu führt, dass wir Zeiger nicht immer verwenden können (wie C und C ++), ohne "unsicher" und "falsch" eingeben zu müssen Ändern Sie die Compiler-Option?

Zur Klarstellung: Ich weiß, was "unsicherer" und "sicherer" Code ist. Es ist nur eine Frage, warum müssen wir all die zusätzliche Arbeit (ok, nicht so viel extra) tun, nur um diese Funktionen nutzen zu können.

    
Inisheer 03.03.2009, 16:37
quelle

9 Antworten

9

Es gibt ein Interview mit C # Creator Anders Hejlsberg, das das Thema hier . Grundsätzlich genau das, was @Marc Gravell gesagt hat: Typensicherheit zuerst, Unsicherheiten durch ausdrückliche Erklärung.

Um Ihre Frage zu beantworten: Nichts in der CLR verhindert es; Es ist eine Sprachsprache, die es Ihnen ermöglicht, mit Sicherheitshandschuhen zu arbeiten, wenn Sie mit Typen arbeiten. Wenn Sie die Handschuhe ausziehen wollen, ist es Ihre Wahl, aber Sie müssen die aktive Wahl treffen, die Handschuhe auszuziehen.

Bearbeiten:

  

Zur Klarstellung: Ich weiß was   "unsicherer" und "sicherer" Code ist. Es ist nur   eine Frage, warum müssen wir all das tun   Extraarbeit (ok, nicht so viel extra)   nur um diese Funktionen nutzen zu können.

Wie in dem von mir verlinkten Interview erwähnt, war dies eine ausdrückliche Designentscheidung. C # ist im Wesentlichen eine Weiterentwicklung von Java und in Java haben Sie überhaupt keine Zeiger. Aber die Designer wollten Zeiger erlauben; Da C # jedoch normalerweise Java-Entwickler einbinden würde, hielten sie es für das beste, wenn das Verhalten default ähnlich wie Java ist, d. h. keine Zeiger, und dennoch die Verwendung von Zeigern durch explizite Deklaration möglich ist.

Die "Extra-Arbeit" ist also beabsichtigt, Sie zu zwingen, darüber nachzudenken, was Sie tun, bevor Sie es tun. Indem Sie explizit sind, zwingt es Sie, zumindest zu überlegen: "Warum mache ich das? Benötige ich wirklich einen Zeiger, wenn ein Referenztyp ausreicht?"

    
Randolpho 03.03.2009, 16:46
quelle
7

Es geht weitgehend darum, überprüfbar zu sein. Wenn Sie unsafe angeben, sind die Handschuhe ausgeschaltet - das System kann nicht mehr garantieren, dass Ihr Code nicht amok läuft. In den meisten Fällen ist es sehr wünschenswert, in der sicheren Zone zu bleiben.

Dies wird mit partieller Vertrauenswürdigkeit (Add-Ins usw.) auffälliger, ist aber im regulären Code immer noch nützlich.

    
Marc Gravell 03.03.2009 16:40
quelle
3

Tatsächlich macht die CLR überhaupt keine Anforderungen an einen / einen unsicheren Schalter oder ein Schlüsselwort. Tatsächlich hat C ++ / CLI (die C ++ - Sprache, die unter der CLR läuft) keinen solchen / unsicheren Schalter und Zeiger können frei auf der CLR verwendet werden.

Also würde ich Ihre Frage wie folgt formulieren: "Warum benötigt C # die Verwendung von / unsafe, bevor Zeiger verwendet werden können?" Und die Antwort auf diese Frage ist wie in anderen Antworten angegeben: um dem Benutzer zu helfen, eine bewusste Entscheidung zu treffen, die Fähigkeit zu verlieren, in etwas weniger als Full Trust-Modus auf der CLR zu laufen. C ++ erfordert praktisch immer Full Trust für die CLR und C # kann immer dann, wenn Sie Code aufrufen, der Full Trust erfordert, oder wenn Sie Zeiger verwenden.

    
Andrew Arnott 03.03.2009 16:57
quelle
2

Wenn Sie einen unsicheren Block verwenden, hat dies den Effekt, dass der Code nicht verifizierbar ist. Dazu müssen bestimmte Berechtigungen ausgeführt werden, und Sie möchten dies möglicherweise nicht in Ihrer Ausgabe zulassen (insbesondere, wenn Sie sich in einer gemeinsam genutzten Quellumgebung befinden). Daher gibt es einen Schalter im Compiler, der die Freigabe verweigert.

    
casperOne 03.03.2009 16:41
quelle
2

Überlegen Sie es von der entgegengesetzten Seite: Da es nicht als unsicher markiert ist, können Sie daraus schließen, dass der meiste Code standardmäßig "sicher" ist. Was bedeutet es, "sicher" zu sein? Für .Net-Code umfasst dies Folgendes (ohne darauf beschränkt zu sein):

  • Der Garbage Collector kann wie gewohnt weitermachen.
  • Verweise auf einen bestimmten Typ werden auf Objekte dieses Typs (oder null) verweisen.
  • Der Code entspricht garantiert den .Net-Vertrauens- / Sicherheitsanforderungen.
  • Der Code ist mathematisch bewiesen, Speicher nicht direkt außerhalb seiner eigenen AppDomain zu berühren. Es mag trivial erscheinen, aber stellen Sie sich vor, wenn Sie mehrere Anwendungsdomänen in derselben Anwendung haben. Der Programmierer kann sie vertrauensvoll als logisch getrennt behandeln.

Jedes Mal, wenn Sie Zeiger verwenden, haben Sie die Möglichkeit, eine dieser Garantien zu brechen. Daher gibt die Kennzeichnung als unsicher diese Schutzfunktionen auf.

    
Joel Coehoorn 03.03.2009 16:47
quelle
2

Kurz gesagt, .NET möchte, dass Sie Ihre Absicht angeben.

Sicher, der Compiler könnte auf die Notwendigkeit des Flags "unsicher" schließen. Aber die Designer wollen, dass es sich um eine bewusste Entscheidung handelt.

Für mich ähnelt es einer Reihe syntaktischer Anforderungen in C #:

  • kein Schalter ohne Pause
  • keine Abschnitte auf Zugriffsebene "(z. B. die Markierung" public: "in C ++)
  • keine Klassenfelder mit "var"

Das Muster besteht darin, dass Sie sich nicht bewegen oder etwas ändern und sich unbeabsichtigt auf ein anderes auswirken sollten. Im Grunde wollen sie dich davon abhalten, sich "in den Fuß zu schießen".

Viele tolle, informative Antworten hier - vielleicht geht das mehr auf Ihre Frage.

    
harpo 03.03.2009 18:05
quelle
1

Damit ist sofort ersichtlich, welcher Code in Webdiensten ohne erhöhte Berechtigungen nicht ausgeführt wird.

    
Joshua 03.03.2009 16:40
quelle
1

Gute Gewohnheiten pflegen & amp; Sicherheit. Immer wenn Sie einen unsicheren Block in einer Assembly verwenden, wird eine NativeCode-Berechtigung vom Stapel angefordert. Dies könnte natürlich implizit erfolgen, aber könnten wir das private Schlüsselwort auch nicht komplett entfernen? Ich denke, es ist gut, Entwickler dazu zu zwingen, speziell unsicheren Code zu verlangen, bevor sie ihn verwenden können.

    
Mark S. Rasmussen 03.03.2009 16:41
quelle
1

Der wichtigste Unterschied zwischen sicherem und unsicheren Code besteht darin, dass unsicherer Code von dem Garbage Collector von .net nicht erreichbar ist. Automatischer GC ist ein großer Teil der Umgangssprache von .net. Wenn Sie über seine Grenzen hinausgehen, ändern Sie vieles, was Sie von Ihrem Code erwarten können.

Pointer ermöglichen insbesondere die Erstellung von Objekten auf dem Heap ohne GC-Referenzen. Dies führt zu einem anderen guten Grund, Code als "unsicher" zu markieren. Es erleichtert das Eingrenzen eines Speicherlecks, wenn Sie feststellen, dass Sie ein Speicherleck haben.

    
Yes - that Jake. 03.03.2009 16:47
quelle