zoukankan      html  css  js  c++  java
  • C# 【无法修改XX返回值,因为它不是变量】

    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的值。

  • 相关阅读:
    基于SSM框架web搜索功能的实现
    使用APICloud打包webapp
    mac如何运行vue项目
    前端和算法实现:给网站上加上自己的水印(以后用上)
    jQuery常用代码片段
    关于vscode的个人配置
    听说你想用git,安装一下咯
    vue创建项目的一种方法
    用js控制css动画效果@keyframes
    axios的封装和拦截
  • 原文地址:https://www.cnblogs.com/timeObjserver/p/5931299.html
Copyright © 2011-2022 走看看