让我们考虑一下名为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。对不起,如果标题是荒谬的
答案 0 :(得分:10)
Size
是一个结构。作为ValueType,它是不可变的。如果你改变它的属性,它只会修改堆栈中的对象实例,而不是实际的字段。在您的情况下,AvatarSize
属性只能使用结构构造函数设置:new Size(20, 20)
。
答案 1 :(得分:4)
你可以做你想做的唯一方法是定义
public class MutableSize{
public int Height{get;set;}
public int Width{get;set;}
}
然后让AvatarSize返回其中一个而不是Size。
答案 2 :(得分: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采用的方法。
答案 3 :(得分:2)
您可以创建2个新属性myFoo.AvatarSizeWidth并使此属性更改宽度相同的高度..
答案 4 :(得分:2)
唯一的方法是将自己的Size类型作为类(引用)而不是struct(value)。
public class Size
{
public Int32 Width;
public Int32 Height;
}
但这当然会使Size失去作为值类型的一些优点......
答案 5 :(得分:1)
这些Size对象是否具有Height和Width的写入属性?或者他们是只读的吗?
答案 6 :(得分:1)
如果要将结构视为类,则必须创建一个包含类,该类包含对结构类型的隐式转换。下面你可以看到包装类(名为Size,你可以根据需要命名它,没关系),Class1类有一个Size属性,然后是一个如何在Form1类中使用它的例子:
编辑:我使用逆转换(从System.Drawing.Size到此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);
}
}