2009-02-04 7 views
6

Pozwala uważają, że mam własności publicznej o nazwie AvatarSize jak poniżej,Ustawianie Nieruchomość bezpośrednio w C#

public class Foo 
{ 
    ... 

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

    ... 
} 

Teraz jeśli klasa docelowej chce ustawić tę właściwość, wtedy trzeba to zrobić w następujący sposób ,

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

Ale gdy próbuję ustawić go tak,

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

kompilator uzyskać mnie błąd stwierdzający, że nie może zmodyfikować wartości zwracanych. Wiem, dlaczego tak się dzieje, ale chciałbym, aby wspierało to również drugą drogę. Proszę, pomóż mi z rozwiązaniem.

P.S. Niestety, jeśli tytuł jest absurdalny

+0

Czy możesz określić, dlaczego chcesz, aby działało w ten sposób? Obawiam się, że nie ma wielu opcji, poza tym, co powiedział Petoj. –

+0

Pokaż, jak wygląda "Rozmiar". –

+0

Rozmiar jest standardowym typem .Net w przestrzeni nazw System.Drawing. – bang

Odpowiedz

10

Size to struktura. Będąc ValueType jest niezmienny. Jeśli zmienisz taką właściwość, zmodyfikuje ona tylko instancję obiektu w stosie, a nie rzeczywiste pole. W twoim przypadku właściwość AvatarSize można ustawić tylko za pomocą konstruktora struct: new Size(20, 20).

+0

To nie jest tak naprawdę niezmienność, która sprawia, że ​​jest to problem - nawet jeśli byłaby to struktura podlegająca mutacji, nadal miałbyś ten sam problem, ponieważ wartość zwrócona z właściwości byłaby odłączona od samej zmiennej. –

+0

Właściwie OP powiedział, że wie, dlaczego pojawia się problem. Zakładam, że chciał tylko mniej pisać, gdy ma tylko ustawić jedną z właściwości ... Tak więc, moja odpowiedź była taka, aby zawrzeć ją w klasie. Naprawdę nie sądzę, że to najlepszy pomysł, ale jeśli naprawdę tego chcesz, można to zrobić. –

2

Można utworzyć 2 nowe właściwości myFoo.AvatarSizeWidth i sprawiają, że zmiana ta właściwość Width samo dotyczy Wysokość ..

+0

Nie chcę tego w ten sposób. To nie rozwiąże, myFoo.AvatarSize.Height = 20; //.NET style myFoo.AvatarSize.Width = 20; // błąd ten numer –

+0

@Sudarsan: źle zrozumiałeś odpowiedź. Sugeruje, że napiszesz myFoo.AvatarSizeHeight = 20. –

1

robi takie wielkość obiektu mają właściwości zapisu na wysokość i szerokość? Czy są one tylko do odczytu?

+0

Mają właściwości zapisu –

+0

. Rozmiar jest niezmienny. Nie możesz zmienić żadnej z jej wartości. Dlatego kompozytor jęczy. –

4

Jedynym sposobem można zrobić to, co chcesz, definiując

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

a następnie o AvatarSize powrót jednego z nich, a nie od ich wielkości.

2

Jedynym sposobem jest utworzenie własnego typu rozmiaru jako klasy (odniesienia) zamiast struktury (wartość).

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

ale to oczywiście uczynić Rozmiar stracić niektóre z zalet bycia typ wartości ...

1

Jeśli chcesz traktować struct jak klasy, trzeba uczynić klasy otoki ma niejawną konwersję do typu struktury. Poniżej możesz zobaczyć klasę opakowania (o nazwie Rozmiar, możesz nadać jej dowolną nazwę, bez znaczenia), klasę Class1, która ma właściwość Rozmiar, a następnie przykład użycia w klasie Form1:

EDYCJA: Zaktualizowałem klasę Size z konwersją odwrotną (z System.Drawing.Size na tę klasę Size) oraz kilka komentarzy.

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

Jeśli to jest casse, to w jaki sposób obsługiwać Add() dla właściwości typu IList ? tj. jak zezwolić na użycie myFoo.AvatarList = new IList () również myFoo.AvatarList.Add ("foo"); Gdybym musiał podążać twoją drogą, to stałoby się nudne, prawda? –

+0

Przykro mi, ale nie rozumiem, jak to się ma do pierwotnego pytania. Twoje pytanie dotyczyło mienia AvatarSize, nie było nic o liście. –

+0

Zobacz klasy Form1 w moim kodzie, robi wszystko, o co poprosiłeś. –

4

To jest po prostu rozszerzenie o Petoj's answer. Nie chciałbym zmienić rozmiaru - sprawienie, że rzeczy zmienne prowadzi do trudniejszego do zrozumienia kodu w mojej opinii.

Zamiast wprowadzić dwie nowe właściwości, AvatarHeight i 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); } 
    } 

    ... 
} 

Nadal nie można zapisać myFoo.AvatarSize.Width = 20 ale może piszą myFoo.AvatarWidth = 20. Należy pamiętać, że ustawienie szerokości i wysokości osobno będzie mniej wydajne niż ustawienie ich za jednym razem.

Jest to podejście, które Windows Forms przyjmuje, przy okazji.

Powiązane problemy