Property on a property

  • Thread starter Thread starter Flare
  • Start date Start date
F

Flare

Hi...Why can´t I access a property thorug property?

Eg.

class Foo {
public SizeF MySize
{ get { return ms; }
set { ms = value; }
}}

Now, if i try to:
Foo.MySize.Width = 5;

I get: Cannot modify the return value of 'Foo.MySize' because it is not a
variable

Why is it so? Im creating a structure of Shape classes where the base unit
was supossed to have public properties on eg its location and size etc.

As i see i have to make public attributes instead wich not optimal since i
might want to do some validation on set accessors. Of course I could make my
own get/set methods but thats kind of wrong when C#(.net) has properties.

reagards
Anders
 
Hi, Flare

you must either declare property MySize as static, either instantiate some
Foo object and use it to get to SizeF property.
In your sample you are specifying static-style access while using non-static
property.

HTH
Alex
 
I get: Cannot modify the return value of 'Foo.MySize' because it is not a
variable

Why is it so? Im creating a structure of Shape classes where the base unit
was supossed to have public properties on eg its location and size etc.

SizeF is a value type, so if you did modify the returned value you wouldn't
be modifying the contents of the property, just the returned value (which
would then be discarded). The compiler is helping you.

For this particular problem, provide Width and Height properties along with
the 'MySize' property.

n!
 
A getter doesn't return an lvalue: "Even though the syntax for accessing a
property is the same as that for a field, a property is not classified as a
variable. Thus, it is not possible to pass a property as a ref or out
argument." - 10.6

Hmm, wouldn't it be nice if on Tuesday this getter returned an lvalue, i.e.,
the variable x itself...

public bool isTuesday;
public int x = 1;
public int X {
get
{
if (this.isTuesday)
return this.x;
else
return 0;
}
// no setter
}

so client code could say:

if (myFoo.IsTuesday)
myFoo.X = 9; // no setter necessary, we've got the variable!

;-)
 
I did not get what these guys wrote, so here is sample (static), which will
work:

class Foo {

private static SizeF ms;


public static SizeF MySize

{ get { return ms; }

set { ms = value; }

}


void Test() {

float f=Foo.MySize.Width;

}

}

HTH

Alex
 
I did not get what these guys wrote, so here is sample (static), which will
work:

[...]

"static" is not the problem. Try to write

Foo.MySize.Width = 5f;

in your sample. It will not compile.

You have to write :

SizeF s = Foo.MySize;
s.Width = 5f;
 
Hi Alex,

AlexS said:
I did not get what these guys wrote, so here is sample (static), which will
work:

class Foo {

private static SizeF ms;


public static SizeF MySize

{ get { return ms; }

set { ms = value; }

}


void Test() {

float f=Foo.MySize.Width;

}

}

HTH

Alex

You and n! are both right, but you each pointed out a different problem with
the code in the original post. I'm guessing Brad's revelation is beyond us
all. Anyway, you will note from your example that you cannot do something
like this:

void Test()
{
float f=Foo.MySize.Width;
Foo.MySize.Width = f;
}

This is a little convoluted, but: The "Foo.MySize" part of the second line
executes "return ms;", which, because SizeF is a struct, returns a *copy* of
the value of Foo.ms. The compiler *could* interpret the ".Width = f" part as
"assign a value to the Width member of the value returned by Foo.MySize",
but this would be very confusing, as most people would expect that Foo.ms
would be modified by that line of code, which it would not. Hence the error,
which is the compiler saying "Hey, this won't do what you expect it will".

Regards,
Daniel
 
I did not get what these guys wrote, so here is sample (static), which

OK I was very unclear before i see. Static would be a very undesired
Solution. This is my real problem

public class Shape
{
public SizeF ShapeSize
{
set { m_shapesize = value; }
// I now realize due to Daniel post
// that this is not a ref but a byvalue-return
get { return m_shapesize}
}

public Box : Shape
{}

class Test
{
Box b = new Box();
b.ShapeSize.Wdth = 5; // Bad...
}

But that actually sux quite alot for serval resaons. The main beeing that
working with my Shape structrue would be a pain since i almosy always is
wokring in SizeF, RectangleF, PointF and not Width, Height, X, Y...

If i had to make suchs wrapper-prpoerties have to split al assignments up in
atomix assigments! Ugly..and not very programmerfreindly..Have i missed a
point?

Would it be sensible to make a wrapper for xxxF strctues as real objects?

Regards
Anders
 
Thanks, Daniel

good point!

rgds
Alex

Daniel Pratt said:
Hi Alex,



You and n! are both right, but you each pointed out a different problem with
the code in the original post. I'm guessing Brad's revelation is beyond us
all. Anyway, you will note from your example that you cannot do something
like this:

void Test()
{
float f=Foo.MySize.Width;
Foo.MySize.Width = f;
}

This is a little convoluted, but: The "Foo.MySize" part of the second line
executes "return ms;", which, because SizeF is a struct, returns a *copy* of
the value of Foo.ms. The compiler *could* interpret the ".Width = f" part as
"assign a value to the Width member of the value returned by Foo.MySize",
but this would be very confusing, as most people would expect that Foo.ms
would be modified by that line of code, which it would not. Hence the error,
which is the compiler saying "Hey, this won't do what you expect it will".

Regards,
Daniel
 
Daniel Pratt said:
The compiler *could* interpret the ".Width = f" part as
"assign a value to the Width member of the value returned by Foo.MySize",
but this would be very confusing, ...

My example was to show one reason the compiler actually couldn't do this,
because it would have to assume a certain implementation of the getter.
What if the getter returns a const or literal? Whether a method returns an
lvalue or non-lvalue has to part of the method declaration, it can't depend
on the implementation.
 
But that actually sux quite alot for serval resaons. The main beeing that
working with my Shape structrue would be a pain since i almosy always is
wokring in SizeF, RectangleF, PointF and not Width, Height, X, Y...

I would write it similar to:


public class Shape
{
public SizeF ShapeSize
{
set { m_shapesize = value; }
// I now realize due to Daniel post
// that this is not a ref but a byvalue-return
get { return m_shapesize}
}

public float Width
{
get
{
return m_shapeSize.Width;
}
set
{
m_shapeSize.Width = value;
}
}

And the same again for Height. Allowing users to simply use:

Box b = new Box();
Box.Width = 5;

or similar.

n!
 
And the same again for Height. Allowing users to simply use:
Box b = new Box();
Box.Width = 5;

Yes that is a possiblity. But since im building a "framework" it has to be
as easy and accesible as possible.

Eg i have a property Bounds wich is a rectangleF. Now everytime the user
wants to set this property with he´s own RectangleF structue he has to do
like.

theShapeObj.BoundWidth = aRectF.Width;
theShapeObj.BoundHeight = aRectF..Height;
theShapeObj.BoundX = aRectF.X;
theShapeObj.BoundY = aRectF.Y;

Thats kind of tedious. Then I would rather make a

public ReactangleF Bounds;

or

public SetBound(Reactanglef rect)
{
m_boundRect = rect;
}
Thanks anyway. Guess properties just isnt the right solution for these kind
of types

Anders, Denmark
 
Flare said:
Yes that is a possiblity. But since im building a "framework" it has to be
as easy and accesible as possible.

Eg i have a property Bounds wich is a rectangleF. Now everytime the user
wants to set this property with he´s own RectangleF structue he has to do
like.

theShapeObj.BoundWidth = aRectF.Width;
theShapeObj.BoundHeight = aRectF..Height;
theShapeObj.BoundX = aRectF.X;
theShapeObj.BoundY = aRectF.Y;

Thats kind of tedious. Then I would rather make a

public ReactangleF Bounds;

Why not have a Bounds property of type RectangleF *and* have
Width/Height/X/Y properties?
Thanks anyway. Guess properties just isnt the right solution for these kind
of types

I don't see why not...
 
theShapeObj.BoundWidth = aRectF.Width;
theShapeObj.BoundHeight = aRectF..Height;
theShapeObj.BoundX = aRectF.X;
theShapeObj.BoundY = aRectF.Y;

Thats kind of tedious. Then I would rather make a

As Jon mentioned, I meant you can have a Width property *and* a rectangle
property. *and* a size property *and* a location property,*and* an X
property etc, etc :)

n!
 
As Jon mentioned, I meant you can have a Width property *and* a rectangle
property. *and* a size property *and* a location property,*and* an X
property etc, etc :)

Damn. You guys are absolutely right (of course). Just had convinced myself,
that i could´nt SET a structtype, in the heat. Thats off course the
solution.

Thanks!

Reagards
Anders
 
Sorry Daniel, I've realized I misread you. Anyway my orig point was that if
properties returned "variables" then Flare's original code would have
worked -- but according to 10.6 they don't, and really there's no logical
way they could return variables.

Anyone care anymore? ;)
 
Anyone care anymore? ;)

I always care :) But I think the discussion is here by ended. (At least I
undestand the issues now)

Thanks All
Anders
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top