关于C#的CS1612错误

来源:互联网 发布:助理数据分析师 编辑:程序博客网 时间:2024/05/21 17:18

Cannot modify the return value of 'expression' because it is not a variable
无法修改“expression”的返回值,因为它不是变量

出现这种错误的最常见情况是:
AnObject.AnStruct.Vaule = xxx;
考虑如下程序:初看没什么问题,实际上根本无法编译
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    public struct Rectangle
    {
        private int _Width;
        private int _Height;
        public int Width
        {
            get { return _Width; }
            set { _Width = value; }
        }
        public int Height
        {
            get { return _Height; }
            set { _Height = value; }
        }
        public Rectangle(int width, int height)
        {
            this._Width = width;
            this._Height = height;
        }
    }

    public class Draw
    {
        private Rectangle _rect = new Rectangle(0, 0);
        public Rectangle MyRect
        {
            get { return _rect; }
            set { _rect = value; }
        }
        public Draw() { }
        public Draw(int mapWidth, int mapHeight)
        {
            _rect = new Rectangle(mapWidth, mapHeight);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Draw draw = new Draw();
            draw.MyRect.Width = 20;//《== 编译错误
            draw.MyRect.Height = 12;《== 编译错误
        }
    }
}
draw是引用类型,MyRect是struct,也就是值类型,draw.MyRect会调用
public Rectangle MyRect
        {
            get { return _rect; }
        }

而值类型默认是按值传递的,返回的是栈上_rect的一份临时的、本地的拷贝,我们暂且称之为temp_rect,
draw.MyRect.Width = 20 等同于temp_rect.Width = 20;
因此即使能对它进行修改也无法反映到draw.MyRect本身(即_rect)的,即这是一个毫无何意义的操作,因此编译器就从源头上禁止了这样的操作。

解决方法:
1)把struct替换成class,这样,MyRect就成了一个对象(引用类型),draw.MyRect就会返回_rect在堆上的实际地址,修改也会反映到实际的对象
2)如果非要用struct不可的话,需要设置一个中间变量:
            Draw draw = new Draw();
            Rectangle tempRect = new Rectangle();
            tempRect.Width = 20;
            tempRect.Height = 12;
            draw.MyRect = tempRect;
这样实际上是替换draw对象的整个_rect属性。

 
原创粉丝点击