• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#【无法修改XX返回值,因为它不是变量】

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
using UnityEngine;
using System.Collections;
using System.Xml.Linq;
using UnityEditor;
using System;

public class NewBehaviourScript : MonoBehaviour {

    struct MVec3{
        public float x;
        public float y;
        public float z;
    }

    class CTest{
        
        public MVec3 posx;
        public MVec3 pos { set; get; }//等同于下面的写法->

        /*MVec3 dv = new MVec3 ();
        public MVec3 pos{
            set{ dv = value; }
            get{ return dv;}
        }*/

    }

    CTest otest;

    // Use this for initialization
    void Start () {
        otest = new CTest ();

        otest.pos.x = 10;
        otest.posx.x = 123;
        gameObject.transform.position.x = 10;

        Debug.Log ("ot.pos.x={0}" + otest.posx.x);

    }
    // Update is called once per frame
    void Update () {
        Vector3 vec3 = gameObject.transform.position;
    }
}

 编译时出现如下错误:

 可以看到34行和36行都出现了编译错误,而35行则正确编译。原因分析:

C#中,reference类型变量存储在堆上,value类型存储在栈上。pos, posx, position都是值类型,为什么会有不同的编译结果呢。区别在于 pos, position是属性,posx是字段。具体分析如下:

32行:new了一个引用类型CTest的对像otest,这时在堆上为对象分配了一片内存,内存大小为pos的三个float和posx的三个float。

34行:由于pos是一个属性,otest.pos将调用属性的get方法,方法的调用是使用栈来进行的,get方法在栈上分配一个临时变量temp来返回pos的的值。即otest.pos返回了一个分配在栈上的临时变量的地址,而otest.pos.x = 10则是试图对栈上临时变量的X进行赋值。这个操作并非不合法,然而是没有意义的,于是编译器就阻止了我们的这个无意义操作,以避免隐患。同理36行。

明白了这个,就容易理解35行为什么是正确的了。otest.posx是一个正常的取地址操作,表示取出otest所在堆内存中的posx变量的地址,这个地址是对象的堆内存中的。

otest.posx.x = 10则是修改堆内存中posx的x的值。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
使用websocket-sharp来创建c#版本的websocket服务发布时间:2022-07-14
下一篇:
C#时间戳发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap