property - properties in c# with example
C#Propiedades automáticas: ¿Por qué tengo que escribir "get"? conjunto;"? (9)
Si tanto get como set son obligatorios en las propiedades automáticas de C #, ¿por qué tengo que molestarme en especificar "get; set"? ¿en absoluto?
Bueno, obviamente necesitas una forma de desambiguar entre campos y propiedades. Pero, ¿son necesarias las palabras clave realmente necesarias? Por ejemplo, está claro que estas dos declaraciones son diferentes:
public int Foo;
public int Bar { }
Eso podría funcionar. Es decir, es una sintaxis que un compilador podría tener sentido.
Pero luego llegas a una situación en la que un bloque vacío tiene un significado semántico. Eso parece precario.
El compilador necesita saber si desea que genere un getter y / o un setter, o tal vez esté declarando un campo.
Porque necesitas alguna forma de distinguirlo de los campos simples.
También es útil tener diferentes modificadores de acceso, por ejemplo
public int MyProperty { get; private set; }
Si la propiedad no tenía accesores, ¿cómo lo separaría el compilador de un campo? ¿Y qué lo separaría de un campo?
Solo pensé en compartir mis hallazgos sobre este tema.
La codificación de una propiedad como la siguiente, es una llamada de acceso directo de .NET 3.0 " propiedad implementada automáticamente ".
public int MyProperty { get; set; }
Esto te ahorra algo de tipeo. El largo camino para declarar una propiedad es así:
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
Cuando utiliza la "propiedad implementada automáticamente", el compilador genera el código para conectar el get y establecerlo en algún "k_BackingField". A continuación se muestra el código desmontado con Reflector.
public int MyProperty
{
[CompilerGenerated]
get
{
return this.<MyProperty>k__BackingField;
}
[CompilerGenerated]
set
{
this.<MyProperty>k__BackingField = value;
}
}
Código de C # desmontado de IL
También conecta un método para el setter y getter.
[CompilerGenerated]
public void set_MyProperty(int value)
{
this.<MyProperty>k__BackingField = value;
}
[CompilerGenerated]
public int get_MyProperty()
{
return this.<MyProperty>k__BackingField;
}
Código de C # desmontado de IL
Cuando declara una propiedad de solo lectura implementada automáticamente, estableciendo el colocador en privado:
public int MyProperty { get; private set; }
Todo el compilador marca el " conjunto " como privado. El método setter y getter dicen lo mismo.
public int MyProperty
{
[CompilerGenerated]
get
{
return this.<MyProperty>k__BackingField;
}
private [CompilerGenerated]
set
{
this.<MyProperty>k__BackingField = value;
}
}
Código de C # desmontado de IL
Así que no estoy seguro de por qué el marco requiere tanto el get; y establecer; en una propiedad implementada automáticamente. Podrían simplemente no haber escrito el método set y setter si no se hubiera proporcionado. Pero puede haber algún problema en el nivel del compilador que lo haga difícil, no lo sé.
Si nos fijamos en la larga manera de declarar una propiedad de solo lectura:
public int myProperty = 0;
public int MyProperty
{
get { return myProperty; }
}
Y luego mira el código desmontado. El colocador no está allí en absoluto.
public int Test2
{
get
{
return this._test;
}
}
public int get_Test2()
{
return this._test;
}
Código de C # desmontado de IL
Además, porque desde C # 6.0 (en Visual Studio 2015, en el momento de esta respuesta disponible en la versión Ultimate Preview) puede implementar una verdadera propiedad de solo lectura:
public string Name { get; }
public string Name { get; } = "This won''t change even internally";
... a diferencia de la solución actualmente imperfecta con el par getter público / setter privado:
public string Name { get; private set; }
public Constructor() { Name="As initialised"; }
public void Method() { Name="This might be changed internally. By mistake. Or not."; }
Ejemplo de lo anterior a continuación (compilado y ejecutable en línea aquí ).
using System;
public class Propertier {
public string ReadOnlyPlease { get; private set; }
public Propertier() { ReadOnlyPlease="As initialised"; }
public void Method() { ReadOnlyPlease="This might be changed internally"; }
public override string ToString() { return String.Format("[{0}]",ReadOnlyPlease); }
}
public class Program {
static void Main() {
Propertier p=new Propertier();
Console.WriteLine(p);
// p.ReadOnlyPlease="Changing externally!";
// Console.WriteLine(p);
// error CS0272: The property or indexer `Propertier.ReadOnlyPlease'' cannot be used in this context because the set accessor is inaccessible
// That''s good and intended.
// But...
p.Method();
Console.WriteLine(p);
}
}
Otras noticias sabrosas sobre C # 6.0 disponible como video de vista previa oficial aquí .
ERROR: una propiedad o indexador no se puede pasar como un parámetro de salida o ref
Si no especificaste {get; set;}
{get; set;}
entonces el compilador no sabría si es un campo o una propiedad. Esto es importante porque mientras "se ven" idénticos, el compilador los trata de manera diferente. Por ejemplo, llamar a "InitAnInt" en la propiedad genera un error.
class Test
{
public int n;
public int i { get; set; }
public void InitAnInt(out int p)
{
p = 100;
}
public Test()
{
InitAnInt(out n); // This is OK
InitAnInt(out i); // ERROR: A property or indexer may not be passed
// as an out or ref parameter
}
}
No debe crear campos públicos / Variables en las clases, nunca se sabe cuándo querrá cambiarlos para tener accesadores get & set, y luego no sabe qué código va a romper, especialmente si tiene clientes que programan contra su API.
También puede tener diferentes modificadores de acceso para el get & set, por ejemplo, {get; conjunto privado ;} hace que el público y el conjunto sean privados para la clase declarante.
Porque es posible que desee una propiedad de solo lectura:
public int Foo { get; private set; }
O propiedad solo escritura:
public int Foo { private get; set; }
Como nadie lo mencionó ... podría hacer que la propiedad automática sea virtual y anularla:
public virtual int Property { get; set; }
Si no hubiera get / set, ¿cómo se anularía? Tenga en cuenta que puede anular el getter y no el setter :
public override int Property { get { return int.MinValue; } }