¿Cuál es la diferencia entre un campo y una propiedad?

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?

preguntado el 17 de noviembre de 08 a las 06:11

Microsoft responde directamente a esta pregunta (para todos los lenguajes .NET) como parte de su Pautas de diseño de miembros. Para obtener más información, consulte los artículos. Diseño de propiedad y Diseño de campo. Tenga en cuenta que hay una distinción entre ejemplo miembros y estático miembros. -

30 Respuestas

Las propiedades exponen campos. Los campos deben (casi siempre) mantenerse privados para 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 en que acceden las cosas que usan 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 las propiedades no están obligadas a encapsular campos, 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.

Respondido el 22 de enero de 21 a las 07:01

Vale la pena señalar que no se requieren propiedades para encapsular campos. No puede haber ningún campo detrás de la propiedad. Puede ser un cálculo o devolver una constante o lo que sea. - Kent Boogaart

"sin afectar la forma externa en que acceden las cosas que usan su clase". perdóneme si no entiendo correctamente, entonces, pero ¿por qué la necesidad de modificadores de acceso frente a las propiedades en absoluto, si el campo detrás de él parece manejar esto? es decir, ¿por qué hacer que una propiedad no sea pública? - Chucky

Su respuesta fue justo antes de las ediciones y comentarios incorrectos extrañamente votados a favor. Una propiedad siempre debe encapsular uno o más campos y nunca debe hacer ningún trabajo pesado o validación. Si necesita una propiedad como Nombre de usuario o Contraseña para tener validación, cambie su tipo de cadenas a Objetos de valor. Existe un contrato tácito entre un creador de clase y el consumidor. Los campos mantienen el estado, las propiedades exponen el estado utilizando uno o más campos, los vacíos cambian de estado (trabajo pesado) y las funciones realizan consultas (trabajo pesado). Esto no es una piedra, solo expectativas sueltas. - Suamere

@jpaugh Si soy un consumidor de clase, sigo los contratos establecidos por el creador de la clase. Si una propiedad es string, mi contrato es: asignar cualquier carácter de hasta ~ 2 bil de longitud. Si una propiedad es DateTime, mi contrato es: asignar cualquier número dentro de los límites de DateTime, que puedo buscar. Si el creador agrega restricciones a los establecedores, esas restricciones no se comunican. Pero si, en cambio, el creador cambia el tipo de string a Surname, luego su nueva clase de Apellido comunica las restricciones, y la propiedad public Surname LastName no tiene validación de establecedor. También, Surname es reutilizable. - Suamere

Y desde Surname, en mi ejemplo, es reutilizable, no necesita preocuparse más adelante para copiar / pegar esas validaciones en un establecedor de propiedades en otros lugares del código. Tampoco se pregunta si la validación de un apellido es en varios lugares si alguna vez realiza cambios en las reglas comerciales para los apellidos. Echa un vistazo al enlace que publiqué sobre los objetos de valor: Suamere

Los principios de la programación orientada a objetos dicen que el funcionamiento interno de una clase debe estar oculto al mundo exterior. Si expone un campo, en esencia, está exponiendo la implementación interna de la clase. Por lo tanto, ajustamos los campos con Propiedades (o métodos en el caso de Java) para darnos la capacidad de cambiar la implementación sin romper el código que depende de nosotros. Ver que podemos poner 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 de 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
}

respondido 17 nov., 08:09

+1 por mencionar propiedades automáticas. Creo que esto es algo que muchas de las respuestas aquí (y en otros lugares) han olvidado incluir. Sin esta explicación, aún puede ser bastante difícil comprender qué public int myVar { get; set; } realmente representa (y supongo que es la razón de al menos el 50% de los resultados que recibe esta pregunta). - priidu neemre

+1 también por mencionar auto y mencionar cómo funciona ("AutoProperty genera un campo privado para nosotros"). Esta fue la respuesta que estaba buscando para una pregunta que tenía. Al investigar, no vi en la página de MSDN sobre ellos ninguna indicación de que se creó un campo privado y estaba causando confusión. ¿Supongo que eso es lo que esto significa? "Los atributos están permitidos en propiedades implementadas automáticamente, pero obviamente no en los campos de respaldo, ya que no se puede acceder a ellos desde su código fuente. Si debe usar un atributo en el campo de respaldo de una propiedad, simplemente cree una propiedad regular". pero no estaba seguro. - Nyra

Tenga en cuenta que el ejemplo dado no encapsula la sentadilla. Esta propiedad brinda acceso completo al 100% al campo privado, por lo que no está orientado a objetos en absoluto. También podría tener un campo público en este caso. Por supuesto, ayuda (marginalmente) a refactorizar el código en el futuro, pero cualquier IDE que valga la pena puede transformar un campo en una propiedad con unas pocas pulsaciones de teclas. La respuesta puede ser técnicamente correcta sobre cómo funcionan las propiedades, pero no da una buena "explicación OOP" de sus usos. - sara

@kai Estoy de acuerdo en que la respuesta simplificó demasiado las cosas y no muestra todo el poder de una propiedad automática, sin embargo, no estoy de acuerdo en que esto no esté orientado a objetos. Es posible que desee comprobar la diferencia entre campos y propiedades. Los campos no pueden ser virtuales y virtual en sí mismo es parte de la programación orientada a objetos. - Gobe

Por supuesto, hay algunas diferencias funcionales. Yo no llamaria virtual Sin embargo, OOP per se. Es una herramienta que habilita el polimorfismo, que es una de las herramientas clave que HABILITA OOP. Sin embargo, no es OOP en sí mismo, y no hay nada inherentemente OOP en una autopropiedad pública. Tampoco contaría cosas como la reflexión o el enlace de datos relacionados con la programación orientada a objetos. Normalmente, no sería tan pedante al respecto, pero la respuesta mencionó específicamente los principios de OO como la fuerza impulsora detrás del ejemplo de código, y no estoy de acuerdo con eso. - sara

Una diferencia importante es que las interfaces pueden tener propiedades pero no campos. Esto, para mí, subraya que las propiedades deben usarse para definir la interfaz pública de una clase, mientras que los campos están destinados a usarse en el funcionamiento interno privado de una clase. Como regla, rara vez creo campos públicos y, de manera similar, rara vez creo propiedades no públicas.

respondido 17 nov., 08:13

¡Qué curioso son esos escenarios raros! - Ojo de águila

Le daré un par de ejemplos del uso de propiedades que podrían hacer girar los engranajes:

  • Inicialización diferida: Si tiene una propiedad de un objeto que es costoso de cargar, pero no se accede tanto en las ejecuciones normales del código, puede retrasar su carga a través de la propiedad. De esa manera, simplemente está ahí, pero la primera vez que otro módulo intenta llamar a esa propiedad, verifica si el campo subyacente es nulo; si lo es, lo carga, sin que el módulo que lo llama lo sepa. Esto puede acelerar enormemente la inicialización del objeto.
  • Seguimiento sucio: Lo que realmente aprendí de mi propia pregunta aquí en StackOverflow. Cuando tengo muchos objetos cuyos valores pueden haber cambiado durante una ejecución, puedo usar la propiedad para rastrear si es necesario guardarlos en la base de datos o no. Si no ha cambiado una sola propiedad de un objeto, la bandera IsDirty no se activará y, por lo tanto, la funcionalidad de guardado la omitirá al decidir qué necesita volver a la base de datos.

Respondido 05 Jul 18, 05:07

Una pregunta sobre el seguimiento sucio: ¿qué pasaría si pudiera cambiar el campo directamente? No sé si se puede hacer, podría decir: "el objeto no necesita ser guardado si no ha cambiado ni un solo CAMPO de un objeto". por lo tanto, el seguimiento sucio no sería una diferencia, ¿me estoy perdiendo algo? - sitios

@juanpastas: La ventaja de las propiedades con respecto al seguimiento sucio es que si los establecedores de propiedades establecen una bandera "sucia", entonces, en el escenario donde la bandera no está configurada, el código no tendrá que inspeccionar los valores de ninguna propiedad para ver si pudieran haber cambiado. Por el contrario, si un objeto expone sus atributos como campos, entonces el contenido de todos los campos debe compararse con el valor anterior (lo que no solo agrega tiempo para hacer la comparación, sino que también significa que el código debe tienen el valor anterior). - Super gato

Esos son buenos. También le permite activar métodos (como eventos) o registrar cuando el valor se establece o se lee. - coloboxp

Usando Propiedades, puede generar 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 los campos (acceso directo a).

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(){       
     NameChanging?.Invoke(this,EventArgs.Empty);       
 }

 private void OnNameChanged(){
     NameChanged?.Invoke(this,EventArgs.Empty);
 }
}

Respondido el 31 de enero de 20 a las 01:01

Me tomó mucho tiempo encontrar esto. Esto es un MVVM. Gracias ! :) - usuario5039044

Dado que muchos de ellos han explicado con pros y contras técnicos de Properties y Field, es hora de entrar en ejemplos en tiempo real.

1. Propiedades le permite establecer el nivel de acceso de solo lectura

Consideremos el caso de dataTable.Rows.Count y dataTable.Columns[i].Caption. Vienen de la clase DataTable y ambos son públicos para nosotros. La diferencia en el nivel de acceso a ellos es que no podemos establecer un valor para dataTable.Rows.Count pero podemos leer y escribir a dataTable.Columns[i].Caption. ¿Es eso posible a través de Field? ¡¡¡No!!! Esto se puede hacer con Properties solamente.

public class DataTable
{
    public class Rows
    {       
       private string _count;        

       // This Count will be accessable to us but have used only "get" ie, readonly
       public int Count
       {
           get
           {
              return _count;
           }       
       }
    } 

    public class Columns
    {
        private string _caption;        

        // Used both "get" and "set" ie, readable and writable
        public string Caption
        {
           get
           {
              return _caption;
           }
           set
           {
              _caption = value;
           }
       }       
    } 
}

2. Propiedades en PropertyGrid

Podrías haber trabajado con Button en Visual Studio. Sus propiedades se muestran en la PropertyGrid como Text,Name etc. Cuando arrastramos y soltamos un botón, y cuando hacemos clic en las propiedades, automáticamente encontrará la clase Button y filtros Properties y mostrar que en PropertyGrid (dónde PropertyGrid no se mostrará Field aunque sean públicos).

public class Button
{
    private string _text;        
    private string _name;
    private string _someProperty;

    public string Text
    {
        get
        {
           return _text;
        }
        set
        {
           _text = value;
        }
   } 

   public string Name
   {
        get
        {
           return _name;
        }
        set
        {
           _name = value;
        }
   } 

   [Browsable(false)]
   public string SomeProperty
   {
        get
        {
           return _someProperty;
        }
        set
        {
           _someProperty= value;
        }
   } 

In PropertyGrid, las propiedades Name y Text se mostrará, pero no SomeProperty. ¿¿¿Por qué??? Porque las propiedades pueden aceptar Atributos. No se muestra en caso de que [Browsable(false)] Es falso.

3. Puede ejecutar declaraciones dentro de Propiedades

public class Rows
{       
    private string _count;        


    public int Count
    {
        get
        {
           return CalculateNoOfRows();
        }  
    } 

    public int CalculateNoOfRows()
    {
         // Calculation here and finally set the value to _count
         return _count;
    }
}

4. Solo se pueden usar propiedades en la fuente de enlace

Fuente de enlace nos ayuda a disminuir el número de líneas de código. Fields no son aceptadas por BindingSource. Deberíamos usar Properties para eso.

5. Modo de depuración

Considere que estamos usando Field para mantener un valor. En algún momento, necesitamos depurar y verificar dónde el valor se vuelve nulo para ese campo. Será difícil hacerlo cuando el número de líneas de código sea superior a 1000. En tales situaciones, podemos usar Property y puede configurar el modo de depuración dentro Property.

   public string Name
   {
        // Can set debug mode inside get or set
        get
        {
           return _name;
        }
        set
        {
           _name = value;
        }
   }

Respondido 05 Jul 18, 05:07

Estos son hechos interesantes, pero se está perdiendo el sentido de la filosofía de campos y propiedades. - David Ferenczy Rogožan

¿Qué quieres decir con FILISOFÍA? @Dawid Ferenczy - Sarath KS

Consulte, por ejemplo, la respuesta marcada. Pero notó que solo está proporcionando ejemplos de uso, ya que la diferencia entre los campos y las propiedades ya se describió, así que olvidé mi comentario, por favor :) - David Ferenczy Rogožan

Lo he leído, pero obviamente no leíste mi comentario anterior: "Pero notó que solo está proporcionando ejemplos de uso, ya que la diferencia entre los campos y las propiedades ya se describió, así que olvidé mi comentario, por favor :)". - David Ferenczy Rogožan

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

A 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. Generalmente, debes usar campos solo para variables que tienen accesibilidad privada o protegida. Datos que su clase expone al código del cliente debe proporcionarse a través de métodos, propiedades e indexadores. Al utilizar estas construcciones para el acceso indirecto a los campos internos, puede protegerse contra valores de entrada no válidos.

A perfecta 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 fácilmente a los datos y aún así ayuda a promover la seguridad y flexibilidad de métodos. Las propiedades permiten que una clase exponga una forma pública de obtener y establecer valores, mientras oculta el código de implementación o verificación. Se usa un descriptor de acceso de propiedad para devolver el valor de la propiedad, y se usa un descriptor de acceso de conjunto para asignar un nuevo valor.

Respondido el 12 de Septiembre de 13 a las 15:09

Esta es una respuesta increíble, realmente me ayudó a entender esto. - steve baumman

"Una propiedad es un miembro que proporciona un mecanismo flexible para leer, escribir o calcular el valor de un campo privado". Esto tiene más sentido. - Gary

Las propiedades tienen la ventaja principal de permitirle cambiar la forma en que se accede a los datos de un objeto sin romper su interfaz pública. Por ejemplo, si necesita agregar una validación adicional o cambiar un campo almacenado a uno calculado, puede hacerlo fácilmente si inicialmente expuso el campo como una propiedad. Si acaba de exponer un campo directamente, tendrá que cambiar la interfaz pública de su clase para agregar la nueva funcionalidad. Ese cambio rompería los clientes existentes, requiriendo que se recompilen antes de que puedan usar la nueva versión de su código.

Si escribe una biblioteca de clases diseñada para un amplio consumo (como .NET Framework, que es utilizado por millones de personas), eso puede ser un problema. Sin embargo, si está escribiendo una clase utilizada internamente dentro de una base de código pequeña (digamos <= 50 K líneas), realmente no es un gran problema, porque nadie se vería afectado negativamente por sus cambios. En ese caso, todo se reduce a preferencias personales.

respondido 17 nov., 08:10

Las propiedades admiten acceso asimétrico, es decir, puede tener un getter y un setter 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 configurar después de la inicialización.

Las propiedades pueden durar mucho tiempo, tener efectos secundarios e incluso generar excepciones. Los campos son rápidos, sin efectos secundarios y nunca arrojará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 pueden usarse para parámetros out / ref, pero 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 que signifique obtener / establecer el valor.

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

respondido 17 nov., 08:11

Los campos pueden tener todos los problemas de costo de las propiedades cuando el tipo de datos del campo es un objeto con una sobrecarga del operador de conversión; es un problema sutil. - andy abolladura

Las propiedades nunca deberían tener efectos secundarios. Incluso el depurador asume que puede evaluarlos de forma segura. - craig gidney

@Strilanc: Estoy completamente de acuerdo, sin embargo, ese no es siempre el caso. En cuanto al depurador, hay muchos problemas con FuncEval si de eso es de lo que estás hablando. - Brian Rasmussen

En segundo plano, una propiedad se compila en métodos. Entonces un Name la propiedad se compila en get_Name() y set_Name(string value). Puede ver esto si estudia el código compilado. Por lo tanto, hay una sobrecarga de rendimiento (muy) pequeña al usarlos. Normalmente, siempre usará una propiedad si expone un campo al exterior y, a menudo, lo usará internamente si necesita hacer la validación del valor.

Respondido 25 Jul 12, 09:07

Aunque los campos y las propiedades parecen ser similares entre sí, son 2 elementos de lenguaje completamente diferentes.

  1. Los campos son el único mecanismo para almacenar datos a nivel de clase. Los campos son conceptualmente variables en el ámbito de la clase. Si desea almacenar algunos datos en instancias de sus clases (objetos), debe usar campos. No hay otra opción. Aunque las propiedades no pueden almacenar ningún dato, puede parecer que pueden hacerlo. Ver abajo.

  2. Las propiedades, por otro lado, nunca almacenan datos. Son solo los pares de métodos (get y set) que se pueden llamar sintácticamente de una manera similar a los campos y en la mayoría de los casos acceden (para leer o escribir) campos, lo cual es la fuente de cierta confusión. Pero debido a que los métodos de propiedad son (con algunas limitaciones como el prototipo fijo) métodos regulares de C #, pueden hacer cualquier cosa que puedan hacer los métodos regulares. Significa que pueden tener 1000 líneas de código, pueden lanzar excepciones, llamar a otros métodos, incluso pueden ser virtuales, abstractos o anulados. Lo que hace que las propiedades sean especiales es el hecho de que el compilador de C # almacena algunos metadatos adicionales en ensamblados que se pueden usar para buscar propiedades específicas, característica ampliamente utilizada.

Los métodos de propiedad get y set tienen los siguientes prototipos.

PROPERTY_TYPE get();

void set(PROPERTY_TYPE value);

Entonces significa que las propiedades se pueden 'emular' definiendo un campo y 2 métodos correspondientes.

class PropertyEmulation
{
    private string MSomeValue;

    public string GetSomeValue()
    {
        return(MSomeValue);
    }

    public void SetSomeValue(string value)
    {
        MSomeValue=value;
    }
}

Esta emulación de propiedades es típica de los lenguajes de programación que no admiten propiedades, como C ++ estándar. En C #, siempre debe preferir las propiedades como la forma de acceder a sus campos.

Debido a que solo los campos pueden almacenar datos, significa que más campos contiene la clase, más objetos de memoria de dicha clase consumirán. Por otro lado, agregar nuevas propiedades a una clase no hace que los objetos de esa clase sean más grandes. Aquí está el ejemplo.

class OneHundredFields
{
        public int Field1;
        public int Field2;
        ...
        public int Field100;
}

OneHundredFields Instance=new OneHundredFields() // Variable 'Instance' consumes 100*sizeof(int) bytes of memory.

class OneHundredProperties
{
    public int Property1
    {
        get
        {
            return(1000);
        }
        set
        {
            // Empty.
        }
    }

    public int Property2
    {
        get
        {
            return(1000);
        }
        set
        {
            // Empty.
        }
    }

    ...

    public int Property100
    {
        get
        {
            return(1000);
        }
        set
        {
            // Empty.
        }
    }
}

OneHundredProperties Instance=new OneHundredProperties() // !!!!! Variable 'Instance' consumes 0 bytes of memory. (In fact a some bytes are consumed becasue every object contais some auxiliarity data, but size doesn't depend on number of properties).

Aunque los métodos de propiedad pueden hacer cualquier cosa, en la mayoría de los casos sirven como una forma de acceder a los campos de los objetos. Si desea que un campo sea accesible para otras clases, puede hacerlo de 2 formas.

  1. Hacer que los campos sean públicos, no es aconsejable.
  2. Usando propiedades.

Aquí hay una clase que usa campos públicos.

class Name
{
    public string FullName;
    public int YearOfBirth;
    public int Age;
}

Name name=new Name();

name.FullName="Tim Anderson";
name.YearOfBirth=1979;
name.Age=40;

Si bien el código es perfectamente válido, desde el punto de vista del diseño, tiene varios inconvenientes. Debido a que los campos se pueden leer y escribir, no puede evitar que el usuario escriba en los campos. Puede aplicar readonly palabra clave, pero de esta manera, debe inicializar campos de solo lectura solo en constructor. Además, nada le impide almacenar valores no válidos en sus campos.

name.FullName=null;
name.YearOfBirth=2200;
name.Age=-140;

El código es válido, todas las asignaciones se ejecutarán aunque sean ilógicas. Age tiene un valor negativo, YearOfBirth es lejano en el futuro y no corresponde a la edad y FullName es nulo. Con campos no puede evitar que los usuarios de class Name para cometer tales errores.

Aquí hay un código con propiedades que corrige estos problemas.

class Name
{
    private string MFullName="";
    private int MYearOfBirth;

    public string FullName
    {
        get
        {
            return(MFullName);
        }
        set
        {
            if (value==null)
            {
                throw(new InvalidOperationException("Error !"));
            }

            MFullName=value;
        }
    }

    public int YearOfBirth
    {
        get
        {
            return(MYearOfBirth);
        }
        set
        {
            if (MYearOfBirth<1900 || MYearOfBirth>DateTime.Now.Year)
            {
                throw(new InvalidOperationException("Error !"));
            }

            MYearOfBirth=value;
        }
    }

    public int Age
    {
        get
        {
            return(DateTime.Now.Year-MYearOfBirth);
        }
    }

    public string FullNameInUppercase
    {
        get
        {
            return(MFullName.ToUpper());
        }
    }
}

La versión actualizada de la clase tiene las siguientes ventajas.

  1. FullName y YearOfBirth se comprueban en busca de valores no válidos.
  2. Age no se puede escribir. Se calcula de YearOfBirth y año actual.
  3. Una nueva propiedad FullNameInUppercase conversos FullName a MAYÚSCULAS. Este es un pequeño ejemplo artificial de uso de propiedades, donde las propiedades se usan comúnmente para presentar valores de campo en el formato que es más apropiado para el usuario, por ejemplo, usando la configuración regional actual en un número específico de DateTime formato.

Además de esto, las propiedades se pueden definir como virtuales o anuladas, simplemente porque son métodos .NET normales. Se aplican las mismas reglas para los métodos de propiedad que para los métodos regulares.

C # también admite indexadores, que son las propiedades que tienen un parámetro de índice en los métodos de propiedad. Aquí está el ejemplo.

class MyList
{
    private string[]                 MBuffer;

    public MyList()
    {
        MBuffer=new string[100];
    }

    public string this[int Index]
    {
        get
        {
            return(MBuffer[Index]);
        }
        set
        {
            MBuffer[Index]=value;
        }
    }
}

MyList   List=new MyList();

List[10]="ABC";
Console.WriteLine(List[10]);

Dado que C # 3.0 le permite definir propiedades automáticas. Aquí está el ejemplo.

class AutoProps
{
    public int Value1
    {
        get;
        set;
    }

    public int Value2
    {
        get;
        set;
    }
}

Aunque class AutoProps contiene solo propiedades (o parece), puede almacenar 2 valores y el tamaño de los objetos de esta clase es igual a sizeof(Value1)+sizeof(Value2)= 4 + 4 = 8 bytes.

La razón de esto es simple. Cuando define una propiedad automática, el compilador de C # genera código automático que contiene un campo oculto y una propiedad con métodos de propiedad que acceden a este campo oculto. Aquí está el código que produce el compilador.

Aquí hay un código generado por el ILSpy de ensamblado compilado. La clase contiene propiedades y campos ocultos generados.

internal class AutoProps
{
    [CompilerGenerated]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private int <Value1>k__BackingField;

    [CompilerGenerated]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private int <Value2>k__BackingField;

    public int Value1
    {
        [CompilerGenerated]
        get
        {
            return <Value1>k__BackingField;
        }
        [CompilerGenerated]
        set
        {
            <Value1>k__BackingField = value;
        }
    }

    public int Value2
    {
        [CompilerGenerated]
        get
        {
            return <Value2>k__BackingField;
        }
        [CompilerGenerated]
        set
        {
            <Value2>k__BackingField = value;
        }
    }
}

Entonces, como puede ver, el compilador todavía usa los campos para almacenar los valores, ya que los campos son la única forma de almacenar valores en objetos.

Como puede ver, aunque las propiedades y los campos tienen una sintaxis de uso similar, son conceptos muy diferentes. Incluso si usa propiedades o eventos automáticos, los campos ocultos son generados por el compilador donde se almacenan los datos reales.

Si necesita hacer que un valor de campo sea accesible para el mundo exterior (usuarios de su clase), no use campos públicos o protegidos. Los campos siempre deben estar marcados como privados. Las propiedades le permiten realizar comprobaciones de valor, formateo, conversiones, etc. y, en general, hacen que su código sea más seguro, más legible y más extensible para futuras modificaciones.

Respondido el 26 de junio de 19 a las 14:06

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

por ejemplo, si tengo variables nombradas como "id" y "nombre", que son privadas, pero puede haber una situación en la que esta variable sea necesaria para la operación de lectura / escritura fuera de la clase. En esa situación, la propiedad puede ayudarme a que esa variable se lea / escriba según el get / set definido para la propiedad. Una propiedad puede ser readonly / writeonly / readwrite both.

aquí está la demostración

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";
    }
}

Respondido el 29 de diciembre de 13 a las 07:12

La segunda pregunta aquí, "¿cuándo se debe usar un campo en lugar de una propiedad?", Solo se aborda brevemente en esta otra respuesta y un poco este también, pero no muchos detalles.

En general, todas las demás respuestas son acertadas sobre un buen diseño: prefiera exponer propiedades a exponer campos. Aunque probablemente no lo harás regularmente te encuentras diciendo "guau, imagina lo peor que serían las cosas si hubiera hecho de esto un campo en lugar de una propiedad", es tanto Es más raro pensar en una situación en la que dirías "guau, gracias a Dios que usé un campo aquí en lugar de una propiedad".

Pero hay una ventaja que tienen los campos sobre las propiedades, y es su capacidad para usarse como parámetros "ref" / "out". Suponga 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 así:

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

Creo que esta es la forma más rápida de hacerlo, ya que X y 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 medidas que demuestren lo contrario, no hay razón para maldecir. Pero creo que técnicamente no se garantiza que sea 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);
}

Haciendo algo mediciones Yo mismo, la versión con campos toma aproximadamente el 61% del tiempo que la versión con propiedades (.NET 4.6, Windows 7, x64, modo de lanzamiento, sin depurador adjunto). Cuanto más caro el TransformPoint se vuelve menos pronunciada la diferencia. Para repetir esto usted mismo, ejecute con la primera línea comentada y sin comentarios.

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

Definitivamente no quiero parecer que estoy defendiendo que digas "oh, debería comenzar a exponer campos en lugar de propiedades". El punto es que si necesita usar estos miembros con regularidad en llamadas que toman parámetros "ref" o "out", especialmente en algo que podría ser un tipo de valor simple que es poco probable que alguna vez necesite alguno de los elementos de valor agregado de las propiedades, se puede hacer un argumento.

contestado el 23 de mayo de 17 a las 12:05

Además, las propiedades le permiten utilizar la lógica al configurar valores.

Por lo tanto, puede decir que solo desea establecer un valor para un campo entero, si el valor es mayor que x, de lo contrario, genere una excepción.

Característica realmente útil.

respondido 17 nov., 08:10

Si va a utilizar primitivas de subproceso, está obligado a utilizar campos. Las propiedades pueden romper su código enhebrado. Aparte de eso, lo que dijo Cory es correcto.

respondido 24 nov., 08:07

¿desde cuando? bloquee su campo de respaldo dentro de la propiedad y es el equivalente - Sekhat

Las propiedades son métodos y no están incluidas en ningún CIL JIT en la actualidad. Si va a utilizar primitivas de subproceso como Interlocked, necesita tener campos. Verifique sus fuentes. Es cierto que "bloquear" era la palabra incorrecta. - Jonathan C Dickinson

(Esto realmente debería ser 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 propiedad equivalente def simplemente 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 estas publicaciones, parece que no muchos de los presentes estarían de acuerdo tampoco. ¿Qué habrías dicho para intentar cambiar las cosas?

Editar: 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 era un problema.

Respondido el 26 de junio de 09 a las 07:06

Como C # 3.0, el patrón descrito aquí está convenientemente respaldado por una función llamada Propiedades implementadas automáticamente. - DavidRR

Creo que una de las ventajas de C # con Propiedades, ya que tienen la misma API que los campos, por lo que a los clientes de la clase realmente no les importa si están accediendo a una propiedad o un campo. (Esto NO es cierto en C ++, por ejemplo). En la creación de prototipos, creo que es razonable comenzar con campos públicos y luego migrar a las propiedades según sea necesario. Hay un impacto de rendimiento y memoria con las propiedades, y hay escritura adicional. No son gratis. Pero, si cambia de opinión, no necesitará refactorizar ningún código dependiente. - marca lakata

Las propiedades no se pueden usar como parámetros OUT o REF, por lo que cambiar un campo a una propiedad podría generar errores de compilación en el futuro. Si el valor se implementó como una propiedad desde el principio, nunca se habría usado como parámetros OUT o REF (VAR en Pascal / Delphi), y cualquier cambio que realice en el getter / setter sería transparente para el uso. - HeartWare

Técnicamente, no creo que haya una diferencia, porque las propiedades son simplemente envoltorios alrededor de campos creados por el usuario o creados automáticamente por el compilador. El propósito de las propiedades es hacer cumplir la encapsulación y ofrecer una característica similar a un método liviano. Es una mala práctica declarar campos como públicos, pero no tiene ningún problema.

respondido 01 nov., 13:08

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

  class SomeClass
  {
     int numbera; //Field

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

  }

Respondido 10 ago 15, 21:08

Mi diseño de un campo es que un campo necesita ser modificado solo por su padre, de ahí la clase. Como resultado, la variable se vuelve privada, luego para poder dar el derecho a leer las clases / métodos afuera, paso por el sistema de propiedad solo con el Get. A continuación, la propiedad recupera el campo y es de solo lectura. Si quieres modificarlo tienes que pasar por métodos (por ejemplo el constructor) y encuentro que gracias a esta forma de hacerte seguro, tenemos un mejor control sobre nuestro código porque hacemos "flange". Siempre se podría poner todo en público, por lo que en todos los casos posibles, la noción de variables / métodos / clases, etc., en mi opinión, es solo una ayuda para el desarrollo, mantenimiento del código. Por ejemplo, si una persona reanuda un código con campos públicos, puede hacer cualquier cosa y, por lo tanto, cosas "ilógicas" en relación con el objetivo, la lógica de por qué se escribió el código. Es mi punto de vista.

Cuando utilizo un campo privado de modelo clásico / propiedades públicas de solo lectura, para 10 campos privados debería escribir 10 propiedades públicas. El código puede ser mucho más rápido. Descubrí el setter privado y ahora solo uso propiedades públicas con un setter privado. El setter crea en segundo plano un campo privado.

Por eso mi antiguo estilo de programación clásico era:

public class MyClass
{
 private int _id;
 public int ID { get { return _id; } }
 public MyClass(int id)
 {
  _id = id;
 }
}

Mi nuevo estilo de programación:

public class MyClass
{
 public int ID { get; private set; }
 public MyClass(int id)
 {
  ID = id;
 }
}

Respondido el 09 de diciembre de 16 a las 16:12

Si mi mal, lo siento! - tony pinot

Las propiedades encapsulan campos, lo que le permite realizar un procesamiento adicional en el valor que se va a establecer o recuperar. Por lo general, es excesivo usar propiedades si no va a realizar ningún procesamiento previo o posterior en el valor del campo.

respondido 17 nov., 08:10

no, yo siempre uso propiedades, te permite la flexibilidad de cambiar la implementación en cualquier momento sin romper tu API. - Sekhat

Con respecto a la evolución de la API, puede utilizar campos para privada datos sin problemas. Además, en casos extraños en los que desee compartir datos dentro de un ensamblado, puede otorgar acceso a los campos "interno". - Daniel Earwicker

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

Respondido el 16 de diciembre de 13 a las 15:12

Tradicionalmente, los campos privados se establecen mediante métodos getter y setter. En aras de menos código, puede usar propiedades para establecer campos en su lugar.

Respondido 01 Abr '15, 02:04

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

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

Respondido 01 Abr '15, 04:04

De Wikipedia - Programación orientada a objetos:

La programación orientada a objetos (POO) 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 conocido como atributos; y 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 brindar a los consumidores del objeto la ilusión / abstracción de trabajar con los datos del objeto.

Respondido 26 ago 15, 11:08

Información adicional: de forma predeterminada, los accesos get y set son tan accesibles como la propiedad en sí. Puede controlar / restringir la accesibilidad de los accesos 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í todavía se accede públicamente a get (ya que la propiedad es pública), pero set está protegido (un especificador de acceso más restringido).

Respondido 05 Feb 17, 13:02

Piénselo: tiene una habitación y una puerta para entrar a esta habitación. Si desea verificar cómo ingresa quién y asegurar su habitación, entonces debe usar las propiedades; de lo contrario, no habrá ninguna puerta y todos entrarán fácilmente sin ninguna regulación.

class Room {
   public string sectionOne;
   public string sectionTwo;
}

Room r = new Room();
r.sectionOne = "enter";

La gente está entrando en la sección Uno con bastante facilidad, no había ninguna verificación

class Room 
{
   private string sectionOne;
   private string sectionTwo;

   public string SectionOne 
   {
      get 
      {
        return sectionOne; 
      }
      set 
      { 
        sectionOne = Check(value); 
      }
   }
}

Room r = new Room();
r.SectionOne = "enter";

Ahora revisaste a la persona y sabes si tiene algo malo con él.

Respondido el 26 de junio de 17 a las 15:06

Los campos son las variables en las clases. Los campos son los datos que puede 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 escribe los datos, estos se conocen como operadores get y set. La lógica establecida a menudo se puede utilizar para realizar la validación.

Respondido 24 Oct 18, 09:10

La diferencia básica y general es:

Campos

  • SIEMPRE dar acceso tanto a get como a set
  • NO PODER causar efectos secundarios (lanzar excepciones, llamar a métodos, cambiar campos excepto el que se está obteniendo / configurando, etc.)

Propiedades

  • NO SIEMPRE dar acceso tanto a get como a set
  • PUEDEN causar efectos secundarios

Respondido el 15 de junio de 19 a las 20:06

Hola y bienvenido a StackOverflow. Tómese un tiempo para leer la página de ayuda, especialmente las secciones denominadas Cómo responder. Es posible que también desee aprender sobre ejemplo mínimo reproducible. - Presa Oddmar

¡Hola y gracias! ¿Hay algún problema con mi respuesta? Leí todos los anteriores y los encontré demasiado prolijos. La mía es la esencia de la diferencia entre campos y propiedades en c #, creo. Es lo más breve posible, pero aún así explica la cosa. - Ted Mucuzany

Hola @Ted. Trabajé en C # durante unos 12 años y nunca pensé en los efectos secundarios :) Me encantaría saber de ellos. Pero estoy de acuerdo, la respuesta es breve y precisa. Solo necesita un poco más de detalle :) - Presa Oddmar

@Oddmar Dam, los enumeré entre paréntesis. Un ejemplo podría ser este (dotnetfiddle.net/SFWC1d) - Ted Mucuzany

Las propiedades son un tipo especial de miembro de clase, en las propiedades usamos un método Set o Get predefinido. Usan descriptores de acceso mediante los cuales podemos leer, escribir o cambiar los valores de los campos privados.

Por ejemplo, tomemos una clase llamada Employee, con campos privados para el nombre, la edad y Employee_Id. 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 público el campo de la clase y exponerlo es riesgoso, ya que no tendrá control sobre lo que se asigna y se devuelve.

Para entender esto claramente con un ejemplo, tomemos la clase de un estudiante que tiene identificación, contraseña, 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 aprobación debe ser de solo lectura.
  • Si falta el nombre del estudiante, no se debe devolver el nombre.

Para eliminar este problema utilizamos el método Get and 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 del 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;
    }
}

Respondido 18 ago 16, 18:08

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

Las propiedades no nombran las ubicaciones de almacenamiento. En cambio, tienen accesores que leen, escriben o calculan sus valores.

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

Por ejemplo, tenemos un campo entero privado age en el 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 property.

 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 tenemos lógica en get y set accessors, podemos usar la propiedad implementada automáticamente.

Cuando tuLas compilaciones de propiedades auto-implementadas crean un campo privado y anónimo. al que solo se puede acceder a través de los descriptores de acceso get y set.

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 configurar de forma privada una propiedad En esto podemos configurar de forma privada la propiedad auto (configurada con en la clase)

public int MyProperty
{
    get; private set;
}

Puedes lograr lo mismo con este código. En esta característica de conjunto de propiedades no está disponible ya que tenemos que establecer el valor en el campo directamente.

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

Respondido el 14 de junio de 17 a las 18:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.