值类型属性??

来源:互联网 发布:java构造器用法 编辑:程序博客网 时间:2024/05/17 03:21

         再一次由于C#中值类型和引用类型的区别 犯了错误。
         假设在类中包含一些值类型的成员(比如结构,数组),你希望为外部程序提供访问和修改这些成员的能力,同时又不想直接暴露成员,在c#中最常见的做法就是为这样的成员添加一个属性:

struct Matrix
{
       
float m11;
       
float m12;
       ...............
       
float m44;
}


class MyClass
{
         
private Matrix _matrix;
         
public Matrix MyMatrix
         
{
              
get{return _matrix;} 
              
set{_matrix = value:}

           }

}

        这看起来是最正常不过的代码了。可是当你希望单独修改属性中的某个成员时,问题就来了:

MyClass test = new MyClass()
test.MyMatrix.m11 
= 1.0f;

      上面两行代码初看起来似乎没有什么问题,可是当你编译时,编译器会告诉你test.MyMatrix.m11不是一个变量,无法为他赋值!!问题出在哪里呢?好吧,注意了,Matrix是一个值类型,对于值类型来说,总是按值传递的。我们把上面一行代码“翻译”一下它等价于:

Matrix temp = test.MyMatrix;
temp.m11 
= 1.0f;

     现在看到问题所在了把,我们先获得了MyMatrix属性的一个拷贝,然后对这个拷贝赋值,显然,由于temp只是一个临时的中间变量,所以这样的代码是没有意义的。因此C#编译器把它做为了一个编译错误。

    这似乎是一个语言上的缺陷,通常由于性能上的考虑,才会把数据设计为值类型,但在这里,如果我们需要为结构中的某个成员进行修改,就不得不更新整个结构,因为只有test.MyMatrix = someValue才能正常工作。当然,你也许还可以把_matrix直接作为公共成员(这样可能失去一些必要的保护措施),或者为值类型中的每个成员写一个属性(如果你足够疯狂的话),但似乎始终无法获得一引用类型一样简便的访问方法。