2009-02-04 22 views
6

consideremos que tengo una propiedad pública denominada AvatarSize como la siguiente,Configuración de la propiedad de la propiedad directamente en C#

public class Foo 
{ 
    ... 

    public Size AvatarSize 
    { 
    get { return myAvatarSize; } 
    set { myAvatarSize = value; } 
    } 

    ... 
} 

Ahora bien, si una clase objetivo quiere establecer esta propiedad, entonces tienen que hacerlo de la siguiente manera ,

myFoo.AvatarSize = new Size(20, 20); //this is one possible way 

Pero si trato de configurarlo como este,

myFoo.AvatarSize.Height = 20; //.NET style 
myFoo.AvatarSize.Width = 20; //error 

el compilador me consiga una error que indica que no puede modificar los valores de retorno. Sé por qué sucede, pero me gustaría apoyar la segunda vía también. Por favor, ayúdame con una solución.

P.S. Lo siento si el título es absurdo

+0

¿Puedes especificar por qué quieres que funcione de esta manera? Me temo que no hay muchas opciones, además de lo que dijo Petoj. –

+0

Muestra cómo se ve "Tamaño". –

+0

El tamaño es un tipo de valor .Net estándar en el espacio de nombres System.Drawing. – bang

Respuesta

10

Size es una estructura. Al ser un ValueType, es inmutable. Si cambia su propiedad de esa manera, solo modificará una instancia de objeto en la pila, no el campo real. En su caso, la propiedad AvatarSize solo se puede establecer utilizando un constructor de estructura: new Size(20, 20).

+0

No es realmente la inmutabilidad lo que hace que esto sea un problema, incluso si se tratara de una estructura mutable, igual tendría el mismo problema porque el valor devuelto por la propiedad se desasociaría de la variable misma. –

+0

En realidad, el OP dijo que él sabe por qué ocurre el problema. Supongo que solo quería hacer menos tipeo cuando solo tiene que establecer una de las propiedades ... Entonces, mi respuesta fue envolverlo en una clase. Realmente no creo que sea la mejor idea para hacerlo, pero si realmente quieres, se puede hacer. –

2

Se puede crear 2 nuevas propiedades myFoo.AvatarSizeWidth y hacen que este cambio de propiedad de la misma anchura ocurre con Altura ..

+0

No quiero que sea así. No resolverá, myFoo.AvatarSize.Height = 20; //.NET style myFoo.AvatarSize.Width = 20; // error este número –

+0

@Sudarsan: ha entendido mal la respuesta. Está sugiriendo que escriba myFoo.AvatarSizeHeight = 20. –

1

hace estas objeto al tamaño tienen propiedades de escritura de perímetro y altura? ¿O son de solo lectura?

+0

Tienen propiedades de escritura –

+0

No. El tamaño es imparable. No puedes cambiar ninguno de sus valores. Es por eso que el compilador gime. –

4

La única manera que puede hacer lo que quiere es definiendo

public class MutableSize{ 
    public int Height{get;set;} 
    public int Width{get;set;} 
} 

y luego tener AvatarSize devolver uno de aquellos en vez de tamaño.

2

La única manera es hacer su propio tipo de tamaño como clase (referencia) en lugar de struct (valor).

public class Size 
    { 
    public Int32 Width; 
    public Int32 Height; 
    } 

Pero esto, por supuesto que el tamaño de perder algunas de las ventajas de ser un tipo de valor ...

1

Si usted quiere tratar una estructura como una clase, usted tiene que hacer una clase contenedora que tiene una conversión implícita al tipo de estructura. A continuación puede ver la clase contenedora (llamada Tamaño, puede asignarle el nombre que desee, no importa), la clase Class1 que tiene una propiedad Tamaño y luego un ejemplo de cómo se usa en la clase Form1:

EDITAR: Actualicé la clase Tamaño con la conversión inversa (de System.Drawing.Size a esta clase de tamaño) y algunos comentarios.

public class Size 
{ 
    public Size(){} 

    public Size(int width, int height) 
    { 
     this.Width = width; 
     this.Height = height; 
    } 

    public int Width { get; set; } 

    public int Height { get; set; } 

    static public implicit operator System.Drawing.Size(Size convertMe) 
    { 
     return new System.Drawing.Size(convertMe.Width, convertMe.Height); 
    } 

    static public implicit operator Size(System.Drawing.Size convertMe) 
    { 
     return new Size(convertMe.Width, convertMe.Height); 
    } 
} 

class Class1 
{ 
    public Class1() 
    { 
     this.TheSize = new Size(); 
    } 

    public Size TheSize { get; set; } 
} 

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     /// Style 1. 
     Class1 a = new Class1(); 

     a.TheSize = new Size(5, 10); 

     /// Style 2. 
     Class1 c = new Class1(); 

     c.TheSize.Width = 400; 
     c.TheSize.Height = 800; 

     /// The conversion from our Size to System.Drawing.Size 
     this.Size = c.TheSize; 

     Class1 b = new Class1(); 

     /// The opposite conversion 
     b.TheSize = this.Size; 

     Debug.Print("b Size: {0} x {1}", b.TheSize.Width, b.TheSize.Height); 


    } 
} 
+0

Si esta es la casse, ¿cómo manejo el Add() para una propiedad de tipo IList ? es decir, ¿cómo puedo permitir el uso de myFoo.AvatarList = new IList () también myFoo.AvatarList.Add ("foo"); Si tuviera que seguir tu camino, entonces se vuelve tedioso ¿no? –

+0

Lo siento, no veo cómo se relaciona eso con la pregunta original. Tu pregunta era sobre la propiedad AvatarSize, no había nada sobre una lista. –

+0

Ver la clase Form1 en mi código, hace todo lo que solicitó. –

4

Esto es realmente solo una expansión de Petoj's answer. No me decantaría por un tamaño mutable: hacer las cosas mutables lleva a un código más difícil de entender en mi opinión.

En cambio, la introducción de dos nuevas propiedades, AvatarHeight y AvatarWidth:

public class Foo 
{ 
    ... 

    public Size AvatarSize 
    { 
    get { return myAvatarSize; } 
    set { myAvatarSize = value; } 
    } 

    public int AvatarHeight 
    { 
    get { return AvatarSize.Height; } 
    set { AvatarSize = new Size(AvatarWidth, value); } 
    } 

    public int AvatarWidth 
    { 
    get { return AvatarSize.Width; } 
    set { AvatarSize = new Size(value, AvatarHeight); } 
    } 

    ... 
} 

Todavía no se puede escribir myFoo.AvatarSize.Width = 20 pero puede escribir myFoo.AvatarWidth = 20. Tenga en cuenta que configurar el ancho y el alto por separado será menos eficiente que configurarlos de una sola vez.

Este es el enfoque que adopta Windows Forms, por cierto.

Cuestiones relacionadas