2009-04-21 18 views
17

Gibt es eine interne Differenz zwischen der C# syntaktischen Zucker Art der Eigenschaften:Ist es in Ordnung, eine öffentliche Variable in C# zu verwenden, wenn es schreibgeschützt ist?

public string FirstName { get; set; } 

und nur öffentliche Variablen wie folgt zu machen:

public string LastName; 

Ich nehme an, die erste Art und Weise bevorzugt wird und die zweiter zu Gemieden werden. Allerdings sehe ich oft diese Art von Nur-Lese-Eigenschaft wird verwendet, die eine Form des zweiten Typs ist oben:

public readonly string InternalCode; 

Ist das eine Best-Practice-Weg Nur-Lese-Eigenschaft zu erstellen?

using System; 

namespace TestProps 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Customer customer = new Customer(); 
      customer.FirstName = "Jim"; 
      customer.LastName = "Smith"; 
      customer.Show(); 
     } 
    } 

    class Customer 
    { 
     public string FirstName { get; set; } //prefered 
     public string LastName; //avoid 
     public readonly string InternalCode; //??? 

     public Customer() 
     { 
      InternalCode = "234729834723984"; 
     } 

     public void Show() 
     { 
      Console.WriteLine("{0}, {1} ({2})", LastName, FirstName, InternalCode); 
      Console.ReadLine(); 
     } 
    } 
} 

Antwort

17

Da er antwortete nicht (noch) nicht, und niemand sonst diese noch verweist: Es zu diesem Thema ein großer Artikel ist von Jon Skeet sein Buch C# in der Tiefe zur Änderung (geben Kredite an Jon):

Why Properties Matter

+0

Dieser Artikel war ein zwei Seiten direkt auf meine Frage, danke! Ich verstehe daraus, dass Jon nicht einmal "public readonly bool IsValid" genehmigte; es sei denn, wie er am Ende erwähnt, ist es in einer verschachtelten Klasse –

+1

Für diejenigen von uns nur auf der Suche nach einer Antwort und nicht ein langer Artikel, könnten Sie hier einen Spoiler-Alarm hinzufügen und geben Sie uns die Ja oder Nein-Antwort? – DOK

+0

Der Skeet-Artikel macht tatsächlich ein paar Ausnahmen, von denen eine auf diese Frage angewendet werden könnte. Gemäß dem Artikel "mache ich eine kleine Ausnahme für statische schreibgeschützte Felder wie string.Empty". Diese Frage könnte geändert worden sein, und durch Verschieben der Zuweisung vom Konstruktor auf dieselbe Zeile wäre public static readonly string InternalCode = "234729834723984"; Als solches wäre es ein "statisches Readonly-Feld" wie Skeet beschrieben. – John

1

Ja. Es ist in Ordnung, eine öffentliche readonly Variablen zu haben (sie können nur zum Zeitpunkt der Definition oder des Konstruktors initialisiert werden).

z.B. Dezimal.MaxValue

Die Eigenschaft public readonly ist gut, wenn sich der Hintergrundwert ändert (außer dem, mit dem er initialisiert wurde).

z.B. Environment.TickCount

Ich dachte, dass Environment.NewLine eine öffentliche readonly Variable sein wird. Nun, es ist eine öffentliche Eigenschaft (nur erhalten) und der Grund könnte die Kompatibilität zwischen verschiedenen Plattformen sein.

+0

Was ist daran falsch? Bitte geben Sie den Grund bei der Abstimmung an. Es wird mir helfen, meinen Fehler zu erkennen. Vielen Dank. – shahkalpesh

+0

Keine Stimme von mir, aber eigentlich Decimal.MaxValue ist ein const und kein Instanzfeld (Lesen Sie den Artikel von Jon Skeet in meiner Antwort aus Gründen, keine Felder zu entlarven) –

3

Die Verwendung einer Eigenschaft bietet eine Schnittstelle, die resistenter gegenüber Änderungen in der Zukunft ist. Nehmen wir einmal an, dass in der Zukunft eine Entscheidung getroffen wird, dem internen Code ein Präfix hinzuzufügen.

Die Verwendung einer öffentlichen readonly-Variable macht Ihre interne Struktur verfügbar und Sie werden es schwer haben, das Präfix jeder Zeile hinzuzufügen, in der Sie die interne Variable der Klasse verwendet haben.

eine Eigenschaft verwenden, können Sie einfach schreiben die folgende

public string InternalCode { 
    get { return _prefix + _internalCode; } 
} 

und fertig!

+0

sobald Sie alle Ihre Compilerfehler auflösen :-) –

+0

Was Compilerfehler? –

+0

Fehler Der Modifizierer "readonly" ist für diesen Artikel nicht gültig –

3

Meiner Meinung nach ist es in Ordnung, öffentliche Felder offenzulegen (vor allem, wenn sie Readonly oder Const sind). Nachdem ich das gesagt habe, würde ich sagen, dass ich in dem Beispiel, das du präsentierst, wahrscheinlich mit Properties gehen würde, da sie dir 2 Vorteile (über Felder) geben: 1) bessere Einkapselung und vielleicht lässt du deinen Code in der Zukunft und 2) Wenn Sie Daten binden, dann brauchen Sie die Eigenschaften.

0

Kurze Antwort: public konst ist in Ordnung, öffentlicher Read-only nicht unbedingt, öffentlich get ohne müssen nicht zwangsläufig gesetzt. Objekte, die nicht ohne Zuweisung geändert werden können, können in Ordnung sein. Referenztypen sind gefährlich, da Sie ihre Werte immer noch ändern können, auch wenn Sie die Referenz selbst nicht ändern können.

Das Problem mit dem Schlüsselwort readonly ist, dass es nicht bedeutet, was Sie als logisch readonly/unveränderlich verstehen würden. Es bedeutet mehr wie "kann nur in Konstruktor zugewiesen werden". Referenzen können nicht geändert werden, aber ihre Werte können. Es gibt leider kein "echtes" readonly-Schlüsselwort von C#. Siehe auch https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/

Eigenschaften können das Schlüsselwort readonly nicht haben (https://titombo.wordpress.com/2012/11/11/using-the-c-modifiers/). Wie bereits erwähnt, können Sie eine Eigenschaft verwenden und nur get und no set definieren. Sie können diese Eigenschaft jedoch nicht im Konstruktor festlegen. Mit einem privaten Set können Sie die Eigenschaft annywhere in der Klasse nicht nur im Konstruktor festlegen. Das Readonly-Feld wäre etwas restriktiver.

Verwandte Themen