Установка свойства свойства непосредственно в C # - PullRequest
6 голосов
/ 04 февраля 2009

Давайте посмотрим, что у меня есть публичное свойство AvatarSize, как показано ниже,

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. Извините, если название абсурдное

Ответы [ 7 ]

10 голосов
/ 04 февраля 2009

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

4 голосов
/ 04 февраля 2009

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

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

4 голосов
/ 04 февраля 2009

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

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

и затем AvatarSize возвращает один из них вместо Size.

2 голосов
/ 04 февраля 2009

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

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

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

2 голосов
/ 04 февраля 2009

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

1 голос
/ 04 февраля 2009

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

РЕДАКТИРОВАТЬ: я обновил класс Size с обратным преобразованием (из System.Drawing.Size в этот класс 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);


    }
}
1 голос
/ 04 февраля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...