无法修改"List<Vector3>.this[int]"的返回值,因为它不是变量

1 篇文章 1 订阅

使用List写代码的时候遇到了一个“怪异”的现象,无法修改List中对象的属性值。
下面就具体使用代码一起来看一下:
private void test()
{
    List<Vector3> list = new List<Vector3>();
    list.Add(new Vector3(1, 0, 0));
    list.Add(new Vector3(2, 0, 0));
    list.Add(new Vector3(3, 0, 0));

    // 使用下面这句代码的时候就会出现编译错误
    // 错误提示如下
    // 无法修改"List<Vector3>.this[int]"的返回值,因为它不是变量
    list[0].x = 4f;
}

这个就让人比较纳闷了,然后我们尝试使用一下Vector3中的Set方法
private void test()
{
    List<Vector3> list = new List<Vector3>();
    list.Add(new Vector3(1, 0, 0));
    list.Add(new Vector3(2, 0, 0));
    list.Add(new Vector3(3, 0, 0));

    Debug.Log("list[0] = " + list[0]);
    list[0].Set(4f, 0, 0);
    Debug.Log("list[0] = " + list[0]);
}

这次编译器不会报出任何错误,但是通过打印可以发现,两次打印的结果是一样的,O~Shit!
这和我们平常的使用不太一样啊,哪里出问题了呢?
好吧,既然这样,咱们就继续探索一下,新建一个类,然后重新走一边试试
public class AClass
{
    public int x;

    public AClass(int x)
    {
        this.x = x;
    }
}

private void test()
{
    List<AClass> list = new List<AClass>();
    list.Add(new AClass(1));
    list.Add(new AClass(2));
    list.Add(new AClass(3));

    Debug.Log("list[0].x = " + list[0].x);
    list[0].x = 4;
    Debug.Log("list[0].x = " + list[0].x);
}

这次通过打印我们可以发现,list[0].x 的值是被改变了的。到这里,我们就需要想想这到底发生了什么。。

我们需要看看Vector3 和我们创建的 AClass 的不同。这时候你就会发现,Vector3 并不是class,而是一个struct。或许你会问这又代表了什么?
我们知道 list[i] 是继承 IList 中的方法
object this[int index] { get; set; }
那么当get的时候 如果是struct,那么它其实就是一个值传递; 如果是class,它传递的是对象的地址。
再通俗一点就是说:值传递 它返回的是一个临时拷贝,而当你改变这个拷贝的时候,对原来的object是不会起到任何作用的,因此编译器认为这是毫无意义的,就从源头上禁止了这种做法。
当然这是作为左值,尝试去改变的时候,如果是右值,只是使用了它的属性值,这还是可以的。
所以,探索到这里,我们就知道了,这其实就是一个值传递和地址传递的区别,这就不足为怪了。

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值