2009-02-04 2 views
6

Давайте рассмотрим, что у меня есть общественное свойство AvatarSize как следующий,Установка свойства свойства, непосредственно в C#

public class Foo 
{ 
    ... 

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

    ... 
} 

Теперь, если целевой класс хочет установить это свойство, то они должны сделать это следующим образом ,

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

Но если я пытаюсь установить его, как это,

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

компилятор пойми меня что он не может изменить возвращаемые значения. Я знаю, почему это происходит, но я бы хотел, чтобы он поддерживал второй путь. Пожалуйста, помогите мне с решением.

P.S. К сожалению, если название абсурдное

+0

Не могли бы вы указать, почему вы хотите, чтобы он работал таким образом? Боюсь, не так много вариантов, кроме того, что сказал Петий. –

+0

Просьба показать, как выглядит «Размер». –

+0

Размер - стандартный тип .Net в пространстве имен System.Drawing. – bang

ответ

10

Size - это структура. Будучи ValueType, он неизменен. Если вы измените его свойство таким образом, оно изменит только экземпляр объекта в стеке, а не фактическое поле. В вашем случае свойство AvatarSize может быть установлено только с помощью конструктора struct: new Size(20, 20).

+0

На самом деле это неизменность делает эту проблему проблемой - даже если это была измененная структура, у вас все равно будет такая же проблема, потому что значение, возвращаемое из свойства, будет отключено от самой переменной. –

+0

Фактически, ОП сказал, что он знает, почему возникает проблема. Я предполагаю, что он просто хотел сделать меньше набрав, когда ему нужно только установить одно из свойств ... Итак, мой ответ состоял в том, чтобы обернуть его в класс. Я действительно не думаю, что это лучшая идея на самом деле, но если вы действительно этого хотите, это можно сделать. –

2

Вы можете создать 2 новых свойства myFoo.AvatarSizeWidth и сделать это изменение свойства Ширина То же самым для Height ..

+0

Я не хочу этого делать. Он не решит, myFoo.AvatarSize.Height = 20; // Стиль .NET myFoo.AvatarSize.Width = 20; // ошибка этот вопрос – 2009-02-04 08:17:48

+0

@ Сударсан: Вы неправильно поняли ответ. Предполагается, что вы напишете myFoo.AvatarSizeHeight = 20. –

1

ли этого размер объекта имеет свойство записи для ширины и высот? Или они только для чтения?

+0

У них есть свойства записи – 2009-02-04 08:32:43

+0

№ Размер можно поддаваться обработке. Вы не можете изменить какие-либо его значения. Вот почему компилятор стонет. –

4

Единственный способ вы можете делать то, что вы хотите, определяя

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

, а затем с AvatarSize вернуть один из тех, кто вместо размера.

2

Единственный способ - сделать свой собственный тип размера как класс (ссылка) вместо struct (value).

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

Но это, конечно, сделать размер потерять некоторые из преимуществ является типом значения ...

1

Если вы хотите, чтобы лечить, как-структуру класса, вы должны сделать класс-оболочку который имеет неявное преобразование в тип структуры. Ниже вы можете увидеть класс-оболочку (с именем «Размер», вы можете назвать его, как хотите, это не имеет значения), класс Class1, который имеет свойство «Размер», а затем пример того, как все это используется в классе Form1:

EDIT: Я обновил класс размера с обратным преобразованием (от System.Drawing.Size до этого класса размера) и некоторыми комментариями.

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

Если это casse, то как мне обрабатывать Add() для свойства типа IList ?? то есть, как разрешить использование myFoo.AvatarList = новый IList () также myFoo.AvatarList.Add ("foo"); Если бы я должен был следовать вашему пути, тогда это становится утомительным, не так ли? – 2009-02-04 08:48:08

+0

Прошу прощения, я не вижу, как это связано с исходным вопросом. Ваш вопрос касался свойства AvatarSize, ничего не было о списке. –

+0

См. Класс Form1 в моем коде, он делает все, что вы просили. –

4

Это действительно просто расширение Petoj's answer. Я бы не стал менять размер файла, что сделало бы его изменчивым, что, по моему мнению, затруднит понимание кода.

Вместо этого ввести два новых свойства, AvatarHeight и 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); } 
    } 

    ... 
} 

Вы все еще не можете писать myFoo.AvatarSize.Width = 20 но вы можете писать myFoo.AvatarWidth = 20. Обратите внимание, что установка ширины и высоты отдельно будет менее эффективной, чем установка их за один раз.

Это, кстати, подход Windows Forms.

Смежные вопросы