it-swarm.com.de

Unterstreichen oder nicht unterstreichen, das ist die Frage

Gibt es Probleme, private Felder in C # nicht mit einem Unterstrich zu versehen, wenn die Binärversion von anderen Framework-Sprachen verwendet werden soll? Da in C # beispielsweise die Groß- und Kleinschreibung beachtet wird, können Sie ein Feld "foo" und die öffentliche Eigenschaft "Foo" aufrufen und es funktioniert einwandfrei.

Hätte dies any Auswirkungen auf eine Sprache, bei der die Groß- und Kleinschreibung nicht beachtet wird, wie z. B. VB.NET, würde dies zu Problemen mit der CLS-Konformität (oder anderen) führen, wenn die Namen nur durch Groß- und Kleinschreibung unterschieden werden können?

119
TheCodeJunkie

Es wird keine Wirkung haben.

Ein Teil der Empfehlungen für das Schreiben von CLS-kompatiblen Bibliotheken besteht darin, KEINE zwei öffentlichen/geschützten Entitäten zu haben, die sich nur im Einzelfall unterscheiden. Sie sollten z. B. [~ # ~] nicht [~ # ~] haben

public void foo() {...}

und

public void Foo() {...}

was Sie beschreiben, ist kein Problem, da das private Objekt dem Benutzer der Bibliothek nicht zur Verfügung steht

46
Binary Worrier

WICHTIGES UPDATE (12. April 2016):

Wir wurden darauf aufmerksam gemacht, dass der interne Standard des .NET CoreFX-Teams besteht auf der Verwendung der Unterstreichungsnotation ohne Angabe von Gründen. Wenn wir uns jedoch Regel 3 genau ansehen, wird deutlich, dass es ein System von _, t_, s_ Präfixen gibt, das nahelegt, warum _ Gewählt wurde an erster Stelle.

  1. Wir verwenden _camelCase Für interne und private Felder und verwenden, wo möglich, nur Lesezugriff. Präfix-Instanzfelder mit _, Statische Felder mit s_ Und Thread-statische Felder mit t_. Bei Verwendung in statischen Feldern sollte readonly nach static stehen (d. H. static readonly Nicht readonly static).
  2. Wir vermeiden this., Sofern dies nicht unbedingt erforderlich ist.

Wenn Sie also wie ein .NET CoreFX-Team an einem leistungskritischen Code auf Systemebene mit mehreren Threads arbeiten, sollten Sie unbedingt Folgendes tun:

  • ihre Kodierungsstandards einhalten und
  • verwenden Sie die Unterstreichungsnotation und
  • lies diese Antwort nicht weiter

Ansonsten lesen Sie bitte weiter ...

DIE URSPRÜNGLICHE ANTWORT:

Lassen Sie uns zunächst vereinbaren, worüber wir sprechen. Die Frage ist, wie wir über nicht statische Methoden und Konstruktoren einer Klasse/Unterklassen auf Instanzmember zugreifen, wenn Sichtbarkeitsmodifikatoren dies zulassen.

Unterstreichungsnotation

  • schlägt vor, dass Sie das Präfix "_" in den Namen der privaten Felder verwenden
  • es heißt auch, dass Sie niemals "dies" verwenden sollten, es sei denn, es ist absolut notwendig

Diese Notation

  • schlägt vor, dass Sie nur immer "dies" verwenden. um auf ein Instanzmitglied zuzugreifen

Warum gibt es diese Schreibweise?

Weil du so bist

  • unterscheiden Sie einen Parameter von einem Feld, wenn sie denselben Namen haben
  • stellen Sie sicher, dass Sie im Kontext der aktuellen Instanz arbeiten

Beispiel

public class Demo
{
   private String name;
   public Demo(String name) {
       this.name = name;
   }
}

Warum existiert die Unterstreichungsnotation?

Einige Leute mögen es nicht, "dies" einzugeben, aber sie brauchen immer noch eine Möglichkeit, ein Feld und einen Parameter voneinander zu unterscheiden, und sie waren sich einig, "_" vor einem Feld zu verwenden

Beispiel

public class Demo
{
   private String _name;
   public Demo(String name) {
      _name = name;
   }
}

Man könnte denken, es ist nur eine Frage des persönlichen Geschmacks und beide Wege sind gleich gut/schlecht. Es gibt jedoch bestimmte Aspekte, in denen diese Notation die Unterstreichungsnotation übertrifft:

Klarheit

  • die Unterstreichungsnotation wirft Namen auf
  • diese Schreibweise hält Namen intakt

Kognitive Belastung

  • die Unterstreichungsnotation ist inkonsistent. Sie behandelt Felder auf besondere Weise, kann jedoch nicht mit anderen Mitgliedern verwendet werden, wenn Sie sich jedes Mal fragen müssen, ob Sie eine Eigenschaft oder ein Feld benötigen

  • diese Schreibweise ist konsistent, Sie müssen nicht denken, Sie verwenden einfach immer "this", um auf ein Mitglied zu verweisen

UPDATE: Wie bereits erwähnt, ist das Folgende kein Vorteilspunkt

Wartung

  • bei der Unterstreichungsnotation müssen Sie beim Refactoring ein Auge auf _ haben, z. B. ein Feld in eine Eigenschaft verwandeln (_ entfernen) oder das Gegenteil (_ hinzufügen)

  • diese Notation hat kein solches Problem

Autovervollständigung

Wenn Sie die Liste der Instanzmitglieder sehen müssen:

  • die Unterstreichungsnotation hilft Ihnen nicht viel, denn wenn Sie "_" eingeben, zeigt Ihnen das Popup "Autocomplete" die privaten Felder und alle Typen, die in den verknüpften Assemblys verfügbar sind, gemischt mit den übrigen Instanzmitgliedern
  • diese Notation gibt Ihnen eine klare Antwort. Wenn Sie "this" eingeben, sehen Sie nur die Liste der Mitglieder und sonst nichts

Mehrdeutigkeit

Manchmal muss man sich ohne Hilfe von Intellisense mit dem Code auseinandersetzen. Zum Beispiel, wenn Sie Codeüberprüfungen durchführen oder den Quellcode online durchsuchen.

  • die Unterstreichungsnotation ist nicht eindeutig: Wenn Sie Something.SomethingElse sehen, können Sie nicht feststellen, ob Something eine Klasse und SomethingElse eine statische Eigenschaft ist ... oder ob Something eine aktuelle Instanzeigenschaft ist, die eine eigene Eigenschaft von SomethingElse hat

  • diese Schreibweise ist klar: Wenn Sie Something.SomethingElse sehen, kann dies nur eine Klasse mit einer statischen Eigenschaft bedeuten

Erweiterungsmethoden

Sie können Erweiterungsmethoden nicht für die Instanz selbst verwenden, ohne "this" zu verwenden.

  • die Unterstreichungsnotation erfordert, dass Sie "this" nicht verwenden, jedoch mit den Erweiterungsmethoden, die Sie benötigen
  • diese Schreibweise erspart Ihnen das Zögern, Sie verwenden immer "this", Punkt.

Visual Studio-Unterstützung

  • die Unterstreichungsnotation hat in Visual Studio keine eingebaute Unterstützung
  • diese Notation wird von Visual Studio natürlich unterstützt:

    1. http://www.screenr.com/zDCH
    2. "This." Qualification : Es wird bevorzugt, dass allen nicht statischen Feldern, die in nicht statischen Methoden verwendet werden, this. In C # vorangestellt wird.

Offizielle Empfehlungen

Es gibt eine Menge offizieller Richtlinien, in denen eindeutig "Keine Unterstriche verwenden" angegeben ist, insbesondere in C #.

241
Trident D'Gao

Entnommen aus der Microsoft StyleCop-Hilfedatei:

TypeName: FieldNamesMustNotBeginWithUnderscore

CheckId: SA1309

Ursache: Ein Feldname in C # beginnt mit einem Unterstrich.

Regelbeschreibung:

Ein Verstoß gegen diese Regel tritt auf, wenn ein Feldname mit einem Unterstrich beginnt.

Standardmäßig erlaubt StyleCop die Verwendung von Unterstrichen, m_ usw. nicht, um lokale Klassenfelder zu markieren, und zwar zugunsten des Präfixes "this.". Der Vorteil der Verwendung von "this." Besteht darin, dass sie für alle Elementtypen, einschließlich Methoden, Eigenschaften usw. und nicht nur für Felder, gleichermaßen gilt, sodass alle Aufrufe von Klassenmitgliedern sofort erkennbar sind, unabhängig davon, mit welchem ​​Editor der Code angezeigt wird . Ein weiterer Vorteil besteht darin, dass eine schnelle, erkennbare Unterscheidung zwischen Instanzmitgliedern und statischen Mitgliedern erstellt wird, denen kein Präfix vorangestellt wird.

Wenn der Feld- oder Variablenname mit dem Namen eines mit Win32 oder COM verknüpften Elements übereinstimmen soll und daher mit einem Unterstrich beginnen muss, platzieren Sie das Feld oder die Variable in einer speziellen NativeMethods-Klasse. Eine NativeMethods-Klasse ist eine Klasse, die einen Namen mit der Endung NativeMethods enthält und als Platzhalter für Win32- oder COM-Wrapper gedacht ist. StyleCop ignoriert diese Verletzung, wenn das Element in eine NativeMethods-Klasse eingefügt wird.

Eine andere Regelbeschreibung gibt an, dass die bevorzugte Vorgehensweise neben den oben genannten darin besteht, private Felder mit Kleinbuchstaben und öffentliche Felder mit Großbuchstaben zu beginnen.

Bearbeiten: Im Anschluss befindet sich die Projektseite von StyleCop hier: http://code.msdn.Microsoft.com/sourceanalysis . Das Durchlesen der Hilfedatei gibt viel Aufschluss darüber, warum sie verschiedene Stilregeln vorschlagen.

67
Dan Rigby

Da es sich um ein privates Feld handelt, hat dies keine Auswirkungen auf einen Benutzer Ihrer Klasse.

Ich empfehle jedoch die Verwendung eines Unterstrichs für das private Feld, da dies das Verständnis von Code erleichtern kann, z. B .:

private int foo;
public void SetFoo(int foo)
{
  // you have to prefix the private field with "this."
  this.foo = foo;

  // imagine there's lots of code here,
  // so you can't see the method signature



  // when reading the following code, you can't be sure what foo is
  // is it a private field, or a method-argument (or a local variable)??
  if (foo == x)
  {
    ..
  }
}

In unserem Team verwenden wir für private Felder immer ein Unterstrich-Präfix. Wenn ich also Code lese, kann ich sehr leicht private Felder identifizieren und sie von Einheimischen und Argumenten unterscheiden. In gewisser Weise kann der Unterstrich als Kurzfassung von "this" angesehen werden.

24
M4N

Nachdem ich in einer Umgebung gearbeitet hatte, die seitdem sehr spezifische und sehr sinnlose Stilregeln hatte, entwickelte ich meinen eigenen Stil. Dies ist ein Typ, bei dem ich viel hin und her gewechselt habe. Ich habe endlich entschieden, dass private Felder immer _field sein werden, lokale Variablen niemals _ und Kleinbuchstaben haben werden, Variablennamen für Steuerelemente der ungarischen Notation lose folgen und Parameter im Allgemeinen camelCase sein werden.

Ich verabscheue das this. Stichwort es fügt meiner Meinung nach einfach zu viel Code-Rauschen hinzu. Ich liebe es, Resharper überflüssig zu machen. Stichwort.

6 year update: Ich habe die Interna von Dictionary<TKey,T> für eine bestimmte Verwendung des gleichzeitigen Zugriffs und falsches Lesen eines privaten Felds als lokale Variable. Private Felder sollten definitiv nicht dieselbe Namenskonvention wie lokale Variablen haben. Wenn es einen Unterstrich gegeben hätte, wäre das unglaublich offensichtlich gewesen.

14
Chris Marisic

Ich mag den Unterstrich, weil ich dann den Kleinbuchstaben als Methodenparameter verwenden kann:

public class Person
{
    string _firstName;

    public MyClass(string firstName)
    {
        _firstName = firstName;
    }

    public string FirstName
    {
        get { return _firstName; }
    }
}
12
Lance Fisher

Ich mag es immer noch sehr, Unterstriche vor privaten Feldern zu verwenden, aus dem Grund, den Martin erwähnt hat, und auch, weil private Felder dann in IntelliSense zusammensortiert werden. Dies ist trotz der Übelkeit der ungarischen Präfixnotationen im Allgemeinen.

In letzter Zeit stelle ich jedoch fest, dass die Verwendung des Unterstrich-Präfixes für private Mitglieder verpönt ist, obwohl ich nicht ganz sicher bin, warum. Vielleicht weiß jemand anderes? Ist es nur das Präfixprinzip? Oder handelte es sich um eine Namensverfälschung von generischen Typen, die in kompilierten Assemblys unterstrichen wird, oder so etwas?

7
peSHIr

Empfehlung von Style Cop oder nicht, beim Einarbeiten in .NET Framework wird häufig "_" für Membervariablen verwendet. Was auch immer die Macher von Style Cop empfehlen, es ist nicht das, was die Mehrheit der MS-Mitarbeiter verwendet. :) Also bleibe ich beim Unterstrich. Weil ich persönlich viel weniger Fehler mache, wenn ich den Unterstrich benutze, als dies.

5
Michel Bakker

Ich denke, dass Felder auf Klassenebene im Großen und Ganzen ein Fehler bei der Gestaltung der Sprache sind. Ich hätte es vorgezogen, wenn die Eigenschaften von C # einen eigenen lokalen Gültigkeitsbereich hätten:

public int Foo
{
   private int foo;
   get
   {
      return foo;
   }
   set
   {
      foo = value;
   }
}

Das würde es möglich machen, die Verwendung von Feldern ganz einzustellen.

Das einzige Mal, dass ich einem privaten Feld einen Unterstrich voranstelle, ist, wenn für eine Eigenschaft ein separates Hintergrundfeld erforderlich ist. Dies ist auch das einzige Mal, dass ich benutze private Felder. (Und da ich niemals geschützte, interne oder öffentliche Felder verwende, verwende ich nur den Feldzeitraum.) Wenn für eine Variable ein Klassenbereich erforderlich ist, ist dies eine Eigenschaft der Klasse.

4
Robert Rossney

Die _fieldName-Notation für private Felder ist so einfach zu brechen. Mit "this". Notation ist unmöglich zu brechen. Wie würden Sie die _ Notation brechen? Beobachten:

private void MyMethod()
{
  int _myInt = 1; 
  return; 
}

Ich habe gerade gegen deine Namenskonvention verstoßen, aber sie wird kompiliert. Ich würde es vorziehen, eine Namenskonvention zu haben, die a) nicht ungarisch und b) explizit ist. Ich bin dafür, die ungarischen Namen abzuschaffen, und das ist in gewisser Weise angebracht. Anstelle des Objekttyps vor dem Variablennamen haben Sie dessen Zugriffsebene.

Vergleichen Sie dies mit Ruby wo der Name der Variablen @my_number bindet den Namen in den Gültigkeitsbereich ein und ist unzerbrechlich.

edit: Diese Antwort ist negativ geworden. Es ist mir egal, es bleibt.

3
jcollum

Wenn Ihre Assembly CLS-kompatibel sein soll, können Sie das CLSCompliant-Attribut in Ihrer Assemblyinfo-Datei verwenden. Der Compiler wird sich dann beschweren, wenn Ihr Code nicht cls-konforme Inhalte enthält.

Wenn Sie dann über 2 Eigenschaften verfügen, die sich nur für den Fall unterscheiden, gibt der Compiler einen Fehler aus. Auf der anderen Seite gibt es keine Probleme, wenn Sie ein privates Feld und ein öffentliches Eigentum in derselben Klasse haben.

(Aber ich stelle meinen privaten Mitgliedern immer einen Unterstrich voran. Es hilft mir auch zu verdeutlichen, wenn ich meinen Code lese, dass eine bestimmte Variable ein Mitgliedsfeld ist.).

1

Ich mag es aus zwei Gründen, Unterstriche vor meinen privaten Feldern zu verwenden. Wie bereits erwähnt, heben sich die Felder von den zugehörigen Eigenschaften in Code und in Intellisense ab. Der zweite Grund ist, dass ich die gleichen Namenskonventionen verwenden kann, unabhängig davon, ob ich in VB oder C # codiere.

0
Rob Windsor

Es gibt keinerlei Auswirkungen. Wenn Ihr Code kompiliert wird, ist alles, was für den Compiler wichtig ist, der Namespace und die Sichtbarkeit des Felds/der Eigenschaft. Ein Unterstrich ist bei der Benennung eines Bezeichners genauso wichtig wie jedes andere Zeichen. Der wahre Trick besteht darin, eine Konvention zu verwenden, die Sie und die Menschen um Sie herum verstehen werden.

0
Kyland Holmes