none
Sinn einer "automatisch implementierte Eigenschaft" RRS feed

  • Frage

  • Mir ist der Sinn dieses Konstrukts nicht klar:

    public class ChangeMusic
    {

       public string strDir{get; set;}

       .....

    }

    static void Main(string[] args)
    {
       ChangeMusic chgMusic = new ChangeMusic();
       chgMusic.strDir = @"D:\50 Musik\fm4-move\";

    .....

    }

    Die Frage ist folgende:

    Die Belegung der globalen Klassenvar. strDir kann ich auch ohne die Verwendung der automatisch implementierten Eigenschaft

         public string strDir{get; set;}

    erreichen. Wenn ich die Klassenvar. wie folgt definiere

         public string strDir;

    kann ich diese mit dem selben Statement belegen:

         chgMusic.strDir = @"D:\50 Musik\fm4-move\";

    Wo liegen die Unterschiede. Danke.

     

    Samstag, 29. Januar 2011 20:10

Antworten

  • Hallo L.,

    Die Dokumentation beinhaltet schon sehr gute Erläuterungen für die "best practice" für Feld-Benutzung:

    • Ein Feld sollte primär als Implementierungsdetail verwendet werden. Felder sollten private oder internal sein und durch Verwendung von Eigenschaften verfügbar gemacht werden. Der Zugriff auf eine Eigenschaft ist ebenso einfach wie der Zugriff auf ein Feld, und der Code in Accessoren einer Eigenschaft kann bei einer Erweiterung der Features des Typs modifiziert werden, ohne dass dadurch eine unterbrechende Änderung vorgenommen wird.Eigenschaften, die lediglich den Wert eines privaten oder internen Felds zurückgeben, sind optimiert, sodass ihre Leistung derjenigen des Zugriffs auf ein Feld entspricht. Die Verwendung extern sichtbarer Felder bedeutet keinen Leistungszuwachs gegenüber der Verwendung von Eigenschaften.
      Quelle: [CA1051: Sichtbare Instanzfelder nicht deklarieren] http://msdn.microsoft.com/de-de/library/ms182141.aspx

      Anmerkung von mir zu: "ohne dass dadurch eine unterbrechende Änderung vorgenommen wird": 
      Das entspringt dem OCP-Prinzip , weitere wichtige Prinzipien auch hier -> CCD.

    • Do not use instance fields that are public or protected. If you avoid exposing fields directly to the developer, classes can be versioned more easily because a field cannot be changed to a property while maintaining binary compatibility. Consider providing get and set property accessors for fields instead of making them public. The presence of executable code in get and set property accessors allows later improvements, such as creation of an object on demand, upon usage of the property, or upon a property change notification. The following code example illustrates the correct use of private instance fields with get and set property accessors. Quelle:  [Field Usage Guidelines]  http://msdn.microsoft.com/en-us/library/ta31s3bc(VS.71).aspx
    • Im Allgemeinen sollten Felder nur für Variablen verwendet werden, auf die privat oder geschützt zugegriffen werden kann.Daten, die dem Clientcode von der Klasse verfügbar gemacht werden, sollten durch Methoden, Eigenschaften und Indexer bereitgestellt werden.Mit diesen Konstrukten für indirekten Zugriff auf interne Felder können ungültige Eingabewerte verhindert werden.Ein privates Feld, das über eine öffentliche Eigenschaft bereitgestellte Daten speichert, wird als Sicherungsspeicher oder dahinter liegendes Feld bezeichnet.

      Felder speichern meist Daten, auf die von mehr als einer Klassenmethode zugegriffen werden muss und die über die Lebensdauer einer einzelnen Methode hinaus gespeichert werden müssen.
      So könnte eine Klasse, die ein Kalenderdatum darstellt, drei Felder mit ganzzahligen Werten beinhalten, jeweils für den Tag, den Monat und das Jahr.Variablen, die außerhalb des Bereichs einer einzelnen Methode nicht verwendet werden, sollten als lokale Variablen im Methodentext selbst deklariert werden.
      Quelle: [Felder (C#-Programmierhandbuch)] http://msdn.microsoft.com/de-de/library/ms173118.aspx


    • Hier auch das Versioning angesprochen:
      [Properties vs public fields redux... - Eric Gunnerson's Compendium - Site Home - MSDN Blogs]

    Was automatisch implementierte Eigenschaften betrifft, dienen diese hauptsächlich der Vereinfachung von Szenarien, in denen bei den get/set-Accessoren keine zusätzliche Logik erforderlich ist.


    ciao Frank
    Samstag, 29. Januar 2011 21:21
  • Hallo L

    es geht hier eigentlich weniger um das 'automatische'   (was man eher als optionalen Syntax-'Komfort' beschreiben könnte),
    sondern viel genereller & klassischer um die Problematik von (zu vermeidenden!) öffentlichen Feldern im Gegensatz zu Eigenschaften.
    Denn Eigenschaften haben ja den grossen Vorteil, dass der Zugriff stets 'kontrollierter' über Code erfolgt (getter- & setter-Methoden), und zwar auch bei den automatisch implementierten Eigenschaften, weil der Compiler get&set intern selber (=automatisch) generiert!

    Automatisch implementierte Eigenschaften
    http://msdn.microsoft.com/de-de/library/bb384054.aspx

    Eigenschaften
    http://msdn.microsoft.com/de-de/library/x9fsa0sw.aspx

    Felder
    http://msdn.microsoft.com/de-de/library/ms173118.aspx

    Public Fields versus Automatic Properties
    http://stackoverflow.com/questions/1180860/

    Auto-Properties - useful or not?
    http://stackoverflow.com/questions/9304/
    Samstag, 29. Januar 2011 20:24
  • Am 29.01.2011 23:27, schrieb Roman Faust:

    Geschrieben wurde ja schon einiges zum Thema. Hier nochmal ein kleines Anwendungsbeispiel:


    public class MyEventArgs { public string Value { get; private set; } public MyEventArgs(string value) { Value = value; } }

    Damit hast du mit minimalsten Aufwand eine Readonly-Eigenschaft implementiert ohne erst ein dahinterliegendes privates Feld nutzen zu müssen.

    Das Feld existiert aber dennoch als "<Value>k__BackingField"
    Intern ist der Autoproperty-Code equivalent zu:

    public class MyEventArgs
    {
      private string @Value_k__BackingField;
      public string Value
      {
        get { return @Value_k__BackingField; }
        private set { @Value_k__BackingField = value; }
      }
      public MyEventArgs2(string value) { Value = value; }
    } 
    Während eine Getter-only Lösung mit Feld auf IL-Ebene "schlanker" ist:
    public class MyEventArgs 
    {
      private string _value;
      public string Value { get { return _value; } }
      public MyEventArgs(string value) { _value = value; }
    } 
    und deren Ctor-Aufruf auch etwas schneller ist, weil eine Feldzuweisung effektiver ist als ein Methodenaufruf ist,
    in dem dann erst die Feldzuweisung erfolgt.
    Man spart zwar also etwas Tipparbeit, aber es kostet Laufzeit und Speicher

    Christoph

    Samstag, 29. Januar 2011 23:51

Alle Antworten

  • Hallo L

    es geht hier eigentlich weniger um das 'automatische'   (was man eher als optionalen Syntax-'Komfort' beschreiben könnte),
    sondern viel genereller & klassischer um die Problematik von (zu vermeidenden!) öffentlichen Feldern im Gegensatz zu Eigenschaften.
    Denn Eigenschaften haben ja den grossen Vorteil, dass der Zugriff stets 'kontrollierter' über Code erfolgt (getter- & setter-Methoden), und zwar auch bei den automatisch implementierten Eigenschaften, weil der Compiler get&set intern selber (=automatisch) generiert!

    Automatisch implementierte Eigenschaften
    http://msdn.microsoft.com/de-de/library/bb384054.aspx

    Eigenschaften
    http://msdn.microsoft.com/de-de/library/x9fsa0sw.aspx

    Felder
    http://msdn.microsoft.com/de-de/library/ms173118.aspx

    Public Fields versus Automatic Properties
    http://stackoverflow.com/questions/1180860/

    Auto-Properties - useful or not?
    http://stackoverflow.com/questions/9304/
    Samstag, 29. Januar 2011 20:24
  • Hallo L.,

    Die Dokumentation beinhaltet schon sehr gute Erläuterungen für die "best practice" für Feld-Benutzung:

    • Ein Feld sollte primär als Implementierungsdetail verwendet werden. Felder sollten private oder internal sein und durch Verwendung von Eigenschaften verfügbar gemacht werden. Der Zugriff auf eine Eigenschaft ist ebenso einfach wie der Zugriff auf ein Feld, und der Code in Accessoren einer Eigenschaft kann bei einer Erweiterung der Features des Typs modifiziert werden, ohne dass dadurch eine unterbrechende Änderung vorgenommen wird.Eigenschaften, die lediglich den Wert eines privaten oder internen Felds zurückgeben, sind optimiert, sodass ihre Leistung derjenigen des Zugriffs auf ein Feld entspricht. Die Verwendung extern sichtbarer Felder bedeutet keinen Leistungszuwachs gegenüber der Verwendung von Eigenschaften.
      Quelle: [CA1051: Sichtbare Instanzfelder nicht deklarieren] http://msdn.microsoft.com/de-de/library/ms182141.aspx

      Anmerkung von mir zu: "ohne dass dadurch eine unterbrechende Änderung vorgenommen wird": 
      Das entspringt dem OCP-Prinzip , weitere wichtige Prinzipien auch hier -> CCD.

    • Do not use instance fields that are public or protected. If you avoid exposing fields directly to the developer, classes can be versioned more easily because a field cannot be changed to a property while maintaining binary compatibility. Consider providing get and set property accessors for fields instead of making them public. The presence of executable code in get and set property accessors allows later improvements, such as creation of an object on demand, upon usage of the property, or upon a property change notification. The following code example illustrates the correct use of private instance fields with get and set property accessors. Quelle:  [Field Usage Guidelines]  http://msdn.microsoft.com/en-us/library/ta31s3bc(VS.71).aspx
    • Im Allgemeinen sollten Felder nur für Variablen verwendet werden, auf die privat oder geschützt zugegriffen werden kann.Daten, die dem Clientcode von der Klasse verfügbar gemacht werden, sollten durch Methoden, Eigenschaften und Indexer bereitgestellt werden.Mit diesen Konstrukten für indirekten Zugriff auf interne Felder können ungültige Eingabewerte verhindert werden.Ein privates Feld, das über eine öffentliche Eigenschaft bereitgestellte Daten speichert, wird als Sicherungsspeicher oder dahinter liegendes Feld bezeichnet.

      Felder speichern meist Daten, auf die von mehr als einer Klassenmethode zugegriffen werden muss und die über die Lebensdauer einer einzelnen Methode hinaus gespeichert werden müssen.
      So könnte eine Klasse, die ein Kalenderdatum darstellt, drei Felder mit ganzzahligen Werten beinhalten, jeweils für den Tag, den Monat und das Jahr.Variablen, die außerhalb des Bereichs einer einzelnen Methode nicht verwendet werden, sollten als lokale Variablen im Methodentext selbst deklariert werden.
      Quelle: [Felder (C#-Programmierhandbuch)] http://msdn.microsoft.com/de-de/library/ms173118.aspx


    • Hier auch das Versioning angesprochen:
      [Properties vs public fields redux... - Eric Gunnerson's Compendium - Site Home - MSDN Blogs]

    Was automatisch implementierte Eigenschaften betrifft, dienen diese hauptsächlich der Vereinfachung von Szenarien, in denen bei den get/set-Accessoren keine zusätzliche Logik erforderlich ist.


    ciao Frank
    Samstag, 29. Januar 2011 21:21
  • Die Frage ist folgende:
    Die Belegung der globalen Klassenvar. strDir kann ich auch ohne die Verwendung der automatisch implementierten Eigenschaft
    Wo liegen die Unterschiede. Danke

    Geschrieben wurde ja schon einiges zum Thema. Hier nochmal ein kleines Anwendungsbeispiel:

    public class MyEventArgs
    {
      public string Value { get; private set; }
      public MyEventArgs(string value)
      {
        Value = value;
      }
    }
    

    Damit hast du mit minimalsten Aufwand eine Readonly-Eigenschaft implementiert ohne erst ein dahinterliegendes privates Feld nutzen zu müssen.

    Gruß, Roman

    Samstag, 29. Januar 2011 22:27
  • Am 29.01.2011 23:27, schrieb Roman Faust:

    Geschrieben wurde ja schon einiges zum Thema. Hier nochmal ein kleines Anwendungsbeispiel:


    public class MyEventArgs { public string Value { get; private set; } public MyEventArgs(string value) { Value = value; } }

    Damit hast du mit minimalsten Aufwand eine Readonly-Eigenschaft implementiert ohne erst ein dahinterliegendes privates Feld nutzen zu müssen.

    Das Feld existiert aber dennoch als "<Value>k__BackingField"
    Intern ist der Autoproperty-Code equivalent zu:

    public class MyEventArgs
    {
      private string @Value_k__BackingField;
      public string Value
      {
        get { return @Value_k__BackingField; }
        private set { @Value_k__BackingField = value; }
      }
      public MyEventArgs2(string value) { Value = value; }
    } 
    Während eine Getter-only Lösung mit Feld auf IL-Ebene "schlanker" ist:
    public class MyEventArgs 
    {
      private string _value;
      public string Value { get { return _value; } }
      public MyEventArgs(string value) { _value = value; }
    } 
    und deren Ctor-Aufruf auch etwas schneller ist, weil eine Feldzuweisung effektiver ist als ein Methodenaufruf ist,
    in dem dann erst die Feldzuweisung erfolgt.
    Man spart zwar also etwas Tipparbeit, aber es kostet Laufzeit und Speicher

    Christoph

    Samstag, 29. Januar 2011 23:51
  • Vielen Dank für die ausführlichen Erläuterungen.

    Sonntag, 30. Januar 2011 10:33
  • Hallo L.,

    freut mich, dann schau ggf. mal, ob die Postings hilfreich waren.

     


    ciao Frank
    Sonntag, 30. Januar 2011 11:54