Freigeben über


CA1024: Nach Möglichkeit Eigenschaften verwenden

TypeName

UsePropertiesWhereAppropriate

CheckId

CA1024

Kategorie

Microsoft.Design

Unterbrechende Änderung

Breaking

Ursache

Eine öffentliche oder geschützte Methode hat einen Namen, der mit Get beginnt, sie nimmt keine Parameter an und gibt einen Wert zurück, bei dem es sich nicht um ein Array handelt.

Regelbeschreibung

In den meisten Fällen stellen Eigenschaften Daten dar, während Methoden überwiegend Aktionen ausführen. Da der Zugriff auf Eigenschaften wie der Zugriff auf Felder erfolgt, vereinfacht sich ihre Verwendung. Eine Methode eignet sich gut als Eigenschaft, wenn eine dieser Bedingungen zutrifft:

  • Akzeptiert keine Argumente und gibt die Zustandsinformationen eines Objekts zurück.

  • Akzeptiert ein einzelnes Argument, um den Zustand eines Objekts teilweise festzulegen.

Eigenschaften sollten sich wie Felder verhalten. Wenn die Methode sich nicht so verhalten kann, sollte sie nicht in eine Eigenschaft geändert werden. Methoden sind in den folgenden Situationen besser geeignet als Eigenschaften:

  • Die Methode führt einen zeitaufwändigen Vorgang aus. Die Methode ist deutlich langsamer als die Zeit, die benötigt wird, um ein Feld festzulegen oder abzurufen.

  • Die Methode führt eine Konvertierung aus. Beim Zugriff auf ein Feld wird keine konvertierte Version der Daten zurückgegeben, die im Feld gespeichert sind.

  • Die Get-Methode zeigt eine wahrnehmbare Nebenwirkung. Das Abrufen des Werts eines Felds erzeugt keine Nebenwirkungen.

  • Die Reihenfolge der Ausführung ist wichtig. Das Festlegen des Werts eines Felds setzt nicht das Stattfinden anderer Vorgänge voraus.

  • Das Aufrufen der Methode zweimal hintereinander führt zu unterschiedlichen Ergebnissen.

  • Die Methode ist statisch, gibt jedoch ein Objekt zurück, das vom Aufrufer geändert werden kann. Beim Abrufen eines Feldwerts kann der Aufrufer die vom Feld gespeicherten Daten nicht ändern.

  • Die Methode gibt ein Array zurück.

Behandeln von Verstößen

Um einen Verstoß gegen diese Regel zu beheben, ändern Sie die Methode in eine Eigenschaft.

Wann sollten Warnungen unterdrückt werden?

Unterdrücken Sie eine Warnung dieser Regel, wenn die Methode mindestens eines der zuvor aufgeführten Kriterien erfüllt.

Steuern der Erweiterung von Eigenschaften im Debugger

Ein Grund, warum Programmierer die Verwendung einer Eigenschaft vermeiden, liegt darin, dass diese vom Debugger nicht automatisch erweitert werden soll. Die Eigenschaft kann z. B. die Reservierung eines umfangreichen Objekts oder den Aufruf von P/Invoke beinhalten, ohne dass sie erkennbare Nebeneffekte hat.

Sie können verhindern, dass der Debugger Eigenschaften automatisch erweitert, indem Sie System.Diagnostics.DebuggerBrowsableAttribute anwenden. Das folgende Beispiel zeigt, wie dieses Attribut auf eine Instanzeneigenschaft angewendet wird.

Imports System 
Imports System.Diagnostics 

Namespace Microsoft.Samples 

    Public Class TestClass 

        ' [...] 

        <DebuggerBrowsable(DebuggerBrowsableState.Never)> _ 
        Public ReadOnly Property LargeObject() As LargeObject 
            Get 
                ' Allocate large object 
                ' [...] 
            End Get 
        End Property 

    End Class 

End Namespace
using System; 
using System.Diagnostics; 

namespace Microsoft.Samples 
{ 
    public class TestClass 
    { 
        // [...] 

        [DebuggerBrowsable(DebuggerBrowsableState.Never)] 
        public LargeObject LargeObject 
        { 
            get 
            { 
                // Allocate large object 
                // [...] 

        }
    }
}

Beispiel

Das folgende Beispiel enthält mehrere Methoden, die in Eigenschaften konvertiert werden sollten, und mehrere Methoden, die nicht in Eigenschaften geändert werden sollten, da sie sich nicht wie Felder verhalten.

using System;
using System.Globalization;
using System.Collections;
namespace DesignLibrary
{
   // Illustrates the behavior of rule: 
   //  UsePropertiesWhereAppropriate.

   public class Appointment
   {
      static long nextAppointmentID;
      static double[] discountScale = {5.0, 10.0, 33.0};
      string customerName;
      long customerID;
      DateTime when;

      // Static constructor.
      static Appointment()
      {
         // Initializes the static variable for Next appointment ID.
      }

      // This method will violate the rule, but should not be a property.
      // This method has an observable side effect. 
      // Calling the method twice in succession creates different results.
      public static long GetNextAvailableID()
      {
         nextAppointmentID++;
         return nextAppointmentID - 1;
      }

      // This method will violate the rule, but should not be a property.
      // This method performs a time-consuming operation. 
      // This method returns an array.

      public Appointment[] GetCustomerHistory()
      {
         // Connect to a database to get the customer's appointment history.
         return LoadHistoryFromDB(customerID);
      }

      // This method will violate the rule, but should not be a property.
      // This method is static but returns a mutable object.
      public static double[] GetDiscountScaleForUpdate()
      {
         return discountScale;
      }

      // This method will violate the rule, but should not be a property.
      // This method performs a conversion.
      public string GetWeekDayString()
      {
         return DateTimeFormatInfo.CurrentInfo.GetDayName(when.DayOfWeek);
      }

      // These methods will violate the rule, and should be properties.
      // They each set or return a piece of the current object's state.

      public DayOfWeek GetWeekDay ()
      {
         return when.DayOfWeek;
      }

      public void  SetCustomerName (string customerName)
      {
         this.customerName = customerName;
      }
      public string GetCustomerName ()
      {
         return customerName;
      }

     public void SetCustomerID (long customerID)
      {
         this.customerID = customerID;
      }

      public long GetCustomerID ()
      {
         return customerID;
      }

      public void SetScheduleTime (DateTime when)
      {
         this.when = when;
      }

      public DateTime GetScheduleTime ()
      {
         return when;
      }

      // Time-consuming method that is called by GetCustomerHistory.
      Appointment[] LoadHistoryFromDB(long customerID)
      {
         ArrayList records = new ArrayList();
         // Load from database.
         return (Appointment[])records.ToArray();
      }
   }
}