c# - propiedades - ¿Cuál es la diferencia entre un campo y una propiedad?




set value to property c# (20)

DIFERENCIAS - USOS (cuándo y por qué)

Un campo es una variable que se declara directamente en una clase o estructura. Una clase o estructura puede tener campos de instancia o campos estáticos o ambos. En general, debe usar campos solo para variables que tengan accesibilidad privada o protegida . Los datos que su clase expone al código del cliente deben proporcionarse a través de métodos, propiedades e indizadores. Al utilizar estas construcciones para el acceso indirecto a los campos internos, puede protegerse contra valores de entrada no válidos.

Una propiedad es un miembro que proporciona un mecanismo flexible para leer, escribir o calcular el valor de un campo privado. Las propiedades se pueden usar como si fueran miembros de datos públicos, pero en realidad son métodos especiales llamados accesores . Esto permite acceder a los datos fácilmente y aún así ayuda a promover la seguridad y flexibilidad de los métodos . Las propiedades permiten a una clase exponer una forma pública de obtener y establecer valores, mientras oculta el código de implementación o verificación. Se utiliza un descriptor de acceso de propiedad de obtención para devolver el valor de la propiedad, y se utiliza un descriptor de acceso de conjunto para asignar un nuevo valor.

En C #, ¿qué hace que un campo sea diferente de una propiedad y cuándo se debe usar un campo en lugar de una propiedad?


(Esto debería ser realmente un comentario, pero no puedo publicar un comentario, así que disculpe si no es apropiado como publicación).

Una vez trabajé en un lugar donde la práctica recomendada era usar campos públicos en lugar de propiedades cuando la definición de propiedad equivalente solo hubiera estado accediendo a un campo, como en:

get { return _afield; }
set { _afield = value; }

Su razonamiento fue que el campo público podría convertirse en una propiedad más adelante en el futuro si fuera necesario. Me pareció un poco extraño en ese momento. A juzgar por estos mensajes, parece que no muchos aquí estarían de acuerdo. ¿Qué podrías haber dicho para intentar cambiar las cosas?

Edit: Debo agregar que todo el código base en este lugar se compiló al mismo tiempo, por lo que podrían haber pensado que cambiar la interfaz pública de clases (cambiando un campo público a una propiedad) no fue un problema.


Al usar Propiedades, puede lanzar un evento, cuando se cambia el valor de la propiedad (también conocido como PropertyChangedEvent) o antes de que se cambie el valor para admitir la cancelación.

Esto no es posible con (acceso directo a) campos.

public class Person {
 private string _name;

 public event EventHandler NameChanging;     
 public event EventHandler NameChanged;

 public string Name{
  get
  {
     return _name;
  }
  set
  {
     OnNameChanging();
     _name = value;
     OnNameChanged();
  }
 }

 private void OnNameChanging(){
   EventHandler localEvent = NameChanging;
   if (localEvent != null) {
     localEvent(this,EventArgs.Empty);
   }
 }

 private void OnNameChanged(){
   EventHandler localEvent = NameChanged;
   if (localEvent != null) {
     localEvent(this,EventArgs.Empty);
   }
 }
}

Cuando desea que su variable privada (campo) sea accesible al objeto de su clase desde otras clases, necesita crear propiedades para esas variables.

por ejemplo, si tengo variables nombradas como "id" y "nombre" que son privadas pero puede haber una situación donde esta variable sea necesaria para la operación de lectura / escritura fuera de la clase. En esa situación, la propiedad puede ayudarme a obtener esa variable para leer / escribir, dependiendo de la configuración / obtención definida para la propiedad. Una propiedad puede ser readonly / writeonly / readwrite both.

aqui esta la demo

class Employee
{
    // Private Fields for Employee
    private int id;
    private string name;

    //Property for id variable/field
    public int EmployeeId
    {
       get
       {
          return id;
       }
       set
       {
          id = value;
       }
    }

    //Property for name variable/field
    public string EmployeeName
    {
       get
       {
          return name;
       }
       set
       {
          name = value;
       }
   }
}

class MyMain
{
    public static void Main(string [] args)
    {
       Employee aEmployee = new Employee();
       aEmployee.EmployeeId = 101;
       aEmployee.EmployeeName = "Sundaran S";
    }
}

De Wikipedia - Programación orientada a objetos :

La programación orientada a objetos (OOP) es un paradigma de programación basado en el concepto de "objetos", que son estructuras de datos que contienen datos, en forma de campos , a menudo conocidos como atributos; y el código, en forma de procedimientos, a menudo conocidos como métodos . (énfasis añadido)

Las propiedades son en realidad parte del comportamiento de un objeto, pero están diseñadas para dar a los consumidores del objeto la ilusión / abstracción de trabajar con los datos del objeto.


En el fondo se compila una propiedad en métodos. Por lo tanto, una propiedad de Name se compila en get_Name() y set_Name(string value) . Puedes ver esto si estudias el código compilado. Así que hay una sobrecarga de rendimiento (muy) pequeña cuando se usan. Normalmente, siempre usará una Propiedad si expone un campo al exterior, y con frecuencia lo usará internamente si necesita hacer la validación del valor.


La segunda pregunta aquí, "¿cuándo se debe usar un campo en lugar de una propiedad?", Se trata brevemente en esta otra respuesta y también en esta , pero no en mucho detalle.

En general, todas las demás respuestas son acertadas sobre el buen diseño: prefieren exponer las propiedades a los campos de exposición. Si bien es probable que no se encuentre a sí mismo diciendo "wow, imagine cuánto peor sería la situación si hubiera hecho de esto un campo en lugar de una propiedad", es mucho más raro pensar en una situación en la que diría "wow, gracias a Dios usé un campo aquí en lugar de una propiedad ".

Pero hay una ventaja que los campos tienen sobre las propiedades, y esa es su capacidad para ser utilizados como parámetros "ref" / "out". Supongamos que tiene un método con la siguiente firma:

public void TransformPoint(ref double x, ref double y);

y suponga que desea utilizar ese método para transformar una matriz creada de esta manera:

System.Windows.Point[] points = new Point[1000000];
Initialize(points);

Esta es la forma más rápida de hacerlo, ya que X e Y son propiedades:

for (int i = 0; i < points.Length; i++)
{
    double x = points[i].X;
    double y = points[i].Y;
    TransformPoint(ref x, ref y);
    points[i].X = x;
    points[i].Y = y;
}

¡Y eso va a ser bastante bueno! A menos que tenga mediciones que demuestren lo contrario, no hay razón para lanzar un hedor. Pero creo que no está técnicamente garantizado para ser tan rápido como esto:

internal struct MyPoint
{
    internal double X;
    internal double Y;
}

// ...

MyPoint[] points = new MyPoint[1000000];
Initialize(points);

// ...

for (int i = 0; i < points.Length; i++)
{
    TransformPoint(ref points[i].X, ref points[i].Y);
}

Realizando algunas measurements mí mismo, la versión con campos lleva aproximadamente el 61% del tiempo como la versión con propiedades (.NET 4.6, Windows 7, x64, modo de lanzamiento, sin depurador adjunto). Cuanto más caro sea el método TransformPoint , menos pronunciada será la diferencia. Para repetir esto, ejecute con la primera línea comentada y con ella no comentada.

Incluso si no hubiera beneficios de rendimiento para lo anterior, hay otros lugares donde poder usar los parámetros de referencia y salida podría ser beneficioso, como cuando se llama a la familia de métodos Interlocked o Volatile . Nota: En caso de que esto sea nuevo para usted, Volatile es básicamente una forma de obtener el mismo comportamiento proporcionado por la palabra clave volatile . Como tal, como volatile , no resuelve mágicamente todos los problemas de seguridad de subprocesos como su nombre sugiere que podría.

Definitivamente no quiero parecer que estoy defendiendo que vayas "oh, debería comenzar a exponer campos en lugar de propiedades". El punto es que si necesita usar regularmente estos miembros en llamadas que toman parámetros "ref" o "out", especialmente en algo que podría ser un tipo de valor simple que probablemente no necesite ninguno de los elementos de valor agregado de las propiedades, Se puede hacer un argumento.


Las propiedades admiten el acceso asimétrico, es decir, puede tener un captador y un configurador o solo uno de los dos. De manera similar, las propiedades admiten la accesibilidad individual para getter / setter. Los campos son siempre simétricos, es decir, siempre puede obtener y establecer el valor. La excepción a esto son los campos de solo lectura que obviamente no se pueden establecer después de la inicialización.

Las propiedades pueden ejecutarse durante mucho tiempo, tener efectos secundarios e incluso pueden generar excepciones. Los campos son rápidos, sin efectos secundarios, y nunca lanzarán excepciones. Debido a los efectos secundarios, una propiedad puede devolver un valor diferente para cada llamada (como puede ser el caso de DateTime.Now, es decir, DateTime.Now no siempre es igual a DateTime.Now). Los campos siempre devuelven el mismo valor.

Los campos se pueden usar para los parámetros de salida / referencia, las propiedades no. Las propiedades admiten lógica adicional: esto podría usarse para implementar la carga diferida, entre otras cosas.

Las propiedades admiten un nivel de abstracción al encapsular lo que sea para obtener / establecer el valor.

Use propiedades en la mayoría de los casos, pero trate de evitar los efectos secundarios.


Las propiedades exponen campos. Los campos deben (casi siempre) mantenerse privados a una clase y acceder a ellos a través de obtener y establecer propiedades. Las propiedades proporcionan un nivel de abstracción que le permite cambiar los campos sin afectar la forma externa a la que acceden las cosas que utilizan su clase.

public class MyClass
{
    // this is a field.  It is private to your class and stores the actual data.
    private string _myField;

    // this is a property. When accessed it uses the underlying field,
    // but only exposes the contract, which will not be affected by the underlying field
    public string MyProperty
    {
        get
        {
            return _myField;
        }
        set
        {
            _myField = value;
        }
    }

    // This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
    // used to generate a private field for you
    public int AnotherProperty{get;set;} 
}

@Kent señala que no es necesario que las propiedades encapsulen campos, que podrían hacer un cálculo en otros campos o servir para otros fines.

@GSS señala que también puede hacer otra lógica, como la validación, cuando se accede a una propiedad, otra característica útil.


Las propiedades son un tipo especial de miembro de clase. En las propiedades usamos un método predefinido de Establecer o Obtener. Usan accesores a través de los cuales podemos leer, escribir o cambiar los valores de los campos privados.

Por ejemplo, tomemos una clase llamada Employee , con campos privados para nombre, edad e ID de empleado. No podemos acceder a estos campos desde fuera de la clase, pero podemos acceder a estos campos privados a través de propiedades.

¿Por qué usamos propiedades?

Hacer que el campo de clase sea público y exponerlo es arriesgado, ya que no tendrá control sobre lo que se asigna y devuelve.

Para entender esto claramente con un ejemplo, tomemos una clase de estudiante que tiene una identificación, una marca de paso, un nombre. Ahora en este ejemplo algún problema con el campo público.

  • La identificación no debe ser -ve.
  • El nombre no se puede establecer en nulo
  • La marca de pase debe ser de solo lectura.
  • Si falta el nombre del estudiante, no se debe devolver el nombre.

Para eliminar este problema usamos el método Get y set.

// A simple example
public class student
{
    public int ID;
    public int passmark;
    public string name;
}

public class Program
{
    public static void Main(string[] args)
    {
       student s1 = new student();
       s1.ID = -101; // here ID can't be -ve
       s1.Name = null ; // here Name can't be null
    }
}

Ahora tomamos un ejemplo de método get y set.

public class student
{
    private int _ID;
    private int _passmark;
    private string_name ;
    // for id property
    public void SetID(int ID)
    {
        if(ID<=0)
        {
            throw new exception("student ID should be greater then 0");
        }
        this._ID = ID;
    }
    public int getID()
    {
        return_ID;
    }
}
public class programme
{
    public static void main()
    {
        student s1 = new student ();
        s1.SetID(101);
    }
    // Like this we also can use for Name property
    public void SetName(string Name)
    {
        if(string.IsNullOrEmpty(Name))
        {
            throw new exeception("name can not be null");
        }
        this._Name = Name;
    }
    public string GetName()
    {
        if( string.IsNullOrEmpty(This.Name))
        {
            return "No Name";
        }
        else
        {
            return this._name;
        }
    }
        // Like this we also can use for Passmark property
    public int Getpassmark()
    {
        return this._passmark;
    }
}

Los campos son variables de miembro ordinario o instancias de miembro de una clase. Las propiedades son una abstracción para obtener y establecer sus valores . Las propiedades también se denominan accesores porque ofrecen una forma de cambiar y recuperar un campo si expone un campo de la clase como privado. En general, debe declarar sus variables miembro como privadas, luego declarar o definir propiedades para ellas.

  class SomeClass
  {
     int numbera; //Field

     //Property 
    public static int numbera { get; set;}

  }

Los principios de programación orientados a objetos dicen que, el funcionamiento interno de una clase debe ocultarse del mundo exterior. Si expone un campo, en esencia está exponiendo la implementación interna de la clase. Por lo tanto, envolvemos los campos con Propiedades (o métodos en el caso de Java) para darnos la posibilidad de cambiar la implementación sin romper el código dependiendo de nosotros. Ver como podemos poner la lógica en la propiedad también nos permite realizar la lógica de validación, etc., si la necesitamos. C # 3 tiene la noción posiblemente confusa de autopropiedades. Esto nos permite simplemente definir la Propiedad y el compilador C # 3 generará el campo privado para nosotros.

public class Person
{
   private string _name;

   public string Name
   {
      get
      {
         return _name;
      }
      set
      {
         _name = value;
      }
   }
   public int Age{get;set;} //AutoProperty generates private field for us
}

OMI, las propiedades son solo los pares de funciones / métodos / interfaces "SetXXX ()" "GetXXX ()" que usamos antes, pero son más concisos y elegantes.


Si va a usar primitivas de hilo, se le obliga a usar campos. Las propiedades pueden romper su código enhebrado. Aparte de eso, lo que dijo Cory es correcto.


Te daré un par de ejemplos sobre el uso de propiedades que podrían hacer girar los engranajes:

  • Inicialización perezosa : si tiene una propiedad de un objeto que es costoso de cargar, pero no se tiene acceso a todo eso en las ejecuciones normales del código, puede retrasar su carga a través de la propiedad. De esa manera, simplemente está sentado allí, pero la primera vez que otro módulo intenta llamar a esa propiedad, comprueba si el campo subyacente es nulo; si lo está, sigue adelante y lo carga, desconocido para el módulo que llama. Esto puede acelerar enormemente la inicialización de objetos.
  • Seguimiento sucio: el cual aprendí de mi propia pregunta aquí en . Cuando tengo muchos objetos cuyos valores podrían haber cambiado durante una ejecución, puedo usar la propiedad para rastrear si es necesario volver a guardarlos en la base de datos o no. Si no se ha modificado una sola propiedad de un objeto, el indicador IsDirty no se activará y, por lo tanto, la funcionalidad de guardado se saltará sobre él cuando decida qué necesita volver a la base de datos.

Tradicionalmente, los campos privados se establecen a través de métodos getter y setter. Por el bien de menos código, puede usar propiedades para establecer campos en su lugar.


cuando tienes una clase que es "coche". Las propiedades son color, forma ...

Donde los campos son variables definidas dentro del alcance de una clase.


Información adicional: De forma predeterminada, los accesores de obtención y configuración son tan accesibles como la propiedad en sí. Puede controlar / restringir la accesibilidad del accesor individualmente (para obtener y configurar) aplicando modificadores de acceso más restrictivos en ellos.

Ejemplo:

public string Name
{
    get
    {
        return name;
    }
    protected set
    {
        name = value;
    }
}

Aquí se obtiene acceso público (como la propiedad es pública), pero el conjunto está protegido (un especificador de acceso más restringido).


Las propiedades se utilizan para exponer el campo. Usan accessors (set, get) a través de los cuales los valores de los campos privados se pueden leer, escribir o manipular.

Las propiedades no nombran las ubicaciones de almacenamiento. En su lugar, tienen accesores que leen, escriben o computan sus valores.

Usando propiedades podemos establecer la validación en el tipo de datos que se establece en un campo.

Por ejemplo, tenemos edad de campo de enteros privados en la que deberíamos permitir valores positivos ya que la edad no puede ser negativa.

Podemos hacer esto de dos maneras usando getter y setters y usando la propiedad.

 Using Getter and Setter

    // field
    private int _age;

    // setter
    public void set(int age){
      if (age <=0)
       throw new Exception();

      this._age = age;
    }

    // getter
    public int get (){
      return this._age;
    }

 Now using property we can do the same thing. In the value is a key word

    private int _age;

    public int Age{
    get{
        return this._age;
    }

    set{
       if (value <= 0)
         throw new Exception()
       }
    }

Propiedad implementada automáticamente Si no logramos obtener y establecer accesores podemos usar la propiedad implementada automáticamente.

Cuando u se compila automáticamente, la propiedad crea un campo privado y anónimo al que solo se puede acceder a través de obtener y establecer accesores.

public int Age{get;set;}

Propiedades abstractas Una clase abstracta puede tener una propiedad abstracta, que debe implementarse en la clase derivada

public abstract class Person
   {
      public abstract string Name
      {
         get;
         set;
      }
      public abstract int Age
      {
         get;
         set;
      }
   }

// overriden something like this
// Declare a Name property of type string:
  public override string Name
  {
     get
     {
        return name;
     }
     set
     {
        name = value;
     }
  }

Podemos establecer una propiedad de forma privada. En esto podemos establecer de forma privada la propiedad auto (establecida en la clase)

public int MyProperty
{
    get; private set;
}

Puedes lograr lo mismo con este código. En este conjunto de propiedades, la función no está disponible, ya que tenemos que establecer el valor en el campo directamente.

private int myProperty;
public int MyProperty
{
    get { return myProperty; }
}

Los campos son las variables en las clases. Los campos son los datos que se pueden encapsular mediante el uso de modificadores de acceso.

Las propiedades son similares a los campos en que definen estados y los datos asociados con un objeto.

A diferencia de un campo, una propiedad tiene una sintaxis especial que controla cómo una persona lee los datos y los escribe, estos se conocen como los operadores de obtener y establecer La lógica establecida puede usarse a menudo para hacer la validación.





field