2012-01-15 18 views
6

¿Cómo implementa Setters y Getters en C# la encapsulación? No soy nuevo cuando se trata de estos setters y getters, tengo experiencia en programación, específicamente java. en Java utiliza setters y getters como esteThe C# Shorthand getters and setters

public class Person { 
    private String fName; 

    public void setName(String someName) { 
     fName = someName; 
    } 

    public String getName() { 
     return fName; 
    } 
} 

public class Test { 

    public static void main(String[] args) { 
     Person p = new Person(); 

     p.setName("Bob"); 
     System.out.println(p.getName()); 
    } 
} 

Y en C# con la taquigrafía

public class Person { 
    public string fName{ get; set;} 
} 

¿Cómo funciona el C# taquigrafía captadores y definidores implementan encapsulación en esto? ¿Cómo implemento ese código C# igual que el código java anterior? ¿Hay alguna restricción al respecto? y como base de mi observación, solo puedo usar ese "fName" si está configurado como público, específicamente "cadena pública fName {get; set;}", pero cuando se trata de privacidad, no puedo. pero cuando lo configuro como privado, ya no puedo acceder a él en otros métodos.

+1

Se llaman propiedades. Ver http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx –

Respuesta

10

No le permiten especificar el comportamiento de encapsulado. Lo que hacen es permitirle especificar que esta es una Propiedad en la interfaz pública de su clase, a diferencia de un campo.

La diferencia aquí es que en Java, getters y setters son simplemente métodos que siguen una cierta convención (getXXX, setXXX). En C#, las propiedades son una construcción de primera clase (a pesar de que son básicamente getters y setters detrás de las escenas). Así que C# proporciona esto como una manera abreviada de decir que puede implementar la encapsulación más tarde (por ejemplo, agregar comportamiento al captador o instalador) pero no quiere romper a los consumidores de su clase, por lo que los declara como propiedades iniciales.

En Java:

public class Foo { 
    private String fooName; 
    public String BarName; 
    public String getFooName() { return fooName; } 
    public String setFooName(String fooName) { this.fooName = fooName; } 

} 

En C#:

public class Foo { 
    public String FooName { get; set; } 
    public String BarName; 
} 

supongamos que tiene un FooReader clase de consumidores se define en otro ensamblado que hace referencia al ensamblado Foo:

public class FooReader { 
    public String ReadFoo(Foo foo) { 
     // This returns the Foo **property** 
     return foo.FooName; 
    } 

    public String ReadBar(Foo foo) { 
     // This returns the Bar **field** 
     return foo.BarName; 
    } 
} 

Ahora , cambiando Foo a este no break FooRe Ader:

public class Foo { 
    private String _fooName; 
    public String FooName { get { return _fooName.ToUpper(); } set { _fooName = value; } } 
    public String BarName; 
} 

pero cambiando a esta Foo VOLUNTAD ruptura FooReader- tendrá que volver a compilar:

public class Foo { 
    private String _fooName; 
    private String _barName; 
    public String FooName { get { return _fooName.ToUpper(); } set { _fooName = value; } } 

    // This breaks FooReader because you changed a field to a property 
    public String BarName { get { return _barName.ToUpper(); } set { _barName = value; } } 
} 
+0

Todavía estoy confundido, no me gustaría ser una molestia pero ¿te importaría publicar un ejemplo de algún tipo? con java y C# comparación? – user962206

+0

@ user962206 Puede reemplazar la propiedad simple más tarde por una más compleja con lógica arbitraria si tiene que implementar un comportamiento específico mientras conserva la compatibilidad con el código binario y el código fuente. – Voo

+0

Vea los ejemplos anteriores –

4

Como se dice a sí mismo, la versión C# es una forma abreviada de lo siguiente:

private string _name; 

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

(Tenga en cuenta que el campo privado no es accesible, es un compilador generado. Todo su acceso será a través de la propiedad, incluso desde dentro de la clase)

En comparación con Java, donde getter/setter son simplemente métodos, esta construcción se llama una propiedad en C# y es una característica del compilador.

+2

Excepto que el nombre del campo de respaldo es un nombre generado por el compilador que no se puede utilizar desde el código C#. –

+0

@BenVoigt y es un detalle de implementación sujeto a cambios incluso si logra resolverlo. –

+0

@Femaref ¿Qué es el valor y cómo lo comparo con el código de Java? –

2

en, C# el equivalente del código dentro de la clase de persona sería:

private String _name; 

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

A partir de C# 3, se puede condensar que reduce a:

public string Name { get; set; } 

Esta es una automatically implemented property y el compilador generará automáticamente el mismo código de encapsulado que si fuera a escribirlo a largo plazo. Un campo de respaldo privado se genera automáticamente para usted, así como los métodos get y set. Realmente, una vez que el compilador genera el código IL, lo que tendrá es un campo con dos métodos, get_Name y set_Name, por lo que al usar la propiedad implementada automáticamente, está permitiendo que el compilador genere casi el mismo código que tiene en tu ejemplo de Java

+0

Ohhh, pero ¿cómo puedo agregar valor a mi nombre usando el "nombre de cadena pública {get; set;}"? por ejemplo, voy a crear un objeto de esa clase, Person p = new Person(). entonces, ¿cómo podría llamar a esos setters y getters? en java lo puedo hacer por p.getName, p.setName ("Bib"), pero en C# ¿cómo haré eso? – user962206

+0

En C# usaría 'string personsName = p.Name' para el getter y' p.Name = "something" 'para el setter. –

+0

oh ya veo. pero lo haría, lo uso. como esta Console.WriteLine (p.Name) ?? y la última pregunta, con su respuesta, ¿significa que, hay encapsulación en los getters y setters de mano corta de C#? – user962206

1

Voy a modificar su pregunta ligeramente para proporcionar una mejor comparación. En Java comúnmente tiene captadores públicas y definidores privadas, con ser el constructor del initializor [sic] de la variable, como por ejemplo:

public class Person{ 
    private String fName; 

    public Person (String name) { 
     setName(name); 
    } 

    private void setName(String someName){ 
     fName = someName; 
    } 

    String getName(){ 
     return fName; 
    } 
} 

Con un usuario de la clase sólo ser capaz de recuperar el valor después de la inicialización a través el constructor:

public class Example { 
    Person person = new Person("Fred"); 
    System.out.println(person.getName()); // Allowed 
    System.out.println(person.fName); // Not allowed because fName is a local class variable 
    person.setName("Aaron"); // Not allowed because setName() is a local class method 
} 

Ahora aquí es donde C# puede llegar a ser confuso, ya que en lugar de utilizar Person.getName sólo tiene que utilizar la variable en sí, sin embargo, esta variable puede todavía encapsularse. En Java, se le enseña que las variables de clase deben ser locales (privadas) y solo se debe acceder con getters y setters. C# es esencialmente el mismo, pero la sintaxis y la lógica son diferentes. La reescritura de mi ejemplo en C# sería:

public class Person { 
    public String fName {get; private set;} 

    public Person(String name) { 
     this.fName = name; 
    } 
} 

public class Example { 
    Person person = new Person("Fred"); 
    Console.WriteLine(person.fName); // This is allowed 
    person.fName = "Tony"; // Not allowed because setter is private 
} 

Ahora si usted quiere añadir lógica a su getter y setter utilizando las convenciones anteriores, lo que se necesita para introducir una variable privada local, pero el código en Example y su persona constructor no cambiaría:

class Person { 
    private String _fName; 
    public String fName { 
     get { return _fName + ".addedText"; } 
     private set { _fName = value.ToLower(); } 
    } 
    public Person(String fName) { 
     this.fName = fName; 
    } 
} 

Ahora bien, si esto es mejor o peor que Java es un tanto discutible, pero por lo que he visto el código va a estar fuera de lugar en C# si lo hace algo así como el a continuación, aunque sintaxis, funcionará:

class Person2 { 
    private String fName; 

    public Person2(string fName) { 
     setFname(fName); 
    } 

    private void setFname(String fName) { 
     this.fName = fName.ToLower(); 
    } 

    public String getFname() { 
     return this.fName+ ".addedText"; 
    } 
} 
Cuestiones relacionadas