|  | 网站首页 | .Net研究 | 
您现在的位置: 程序员之路 >> .Net研究 >> 相关资讯 >> 学习体会 >> 文章正文
赞助商链接
频 道 导 航
.Net研究频道栏目导航
相 关 文 章
Effective C# Item 23: Avoid Returning References t           
Effective C# Item 23: Avoid Returning References t
作者:aiyagaze 文章来源:不详 更新时间:2007-5-10 11:53:19

Effective C# Item 23: Avoid Returning References to Internal Class Objects

Effective C# Item 23: Avoid Returning References to Internal Class Objects

      我们知道定义只读属性可以让调用者无法修改该属性的值。但是并不是在所有情况下这种做法都能达到目的。如果我们创建了一个返回引用类型的属性,那么调用者可以对这些对象成员进行任何的操作,包括那些我们不期望的修改操作。考虑下面这段例子:

    public class MyBusinessObject
    
{
        
private DataSet _ds;
        
public DataSet Data
        
{
            
get
            
{
                
return _ds;
            }

        }

    }


    MyBusinessObject bizObj 
= new MyBusinessObject();
    DataSet ds 
= bizObj.Data;
    ds.Tables.Clear();    
//删除了所有的表

      任何MyBusinessObject的客户程序都可以修改它的内部dataset。我们创建只读属性的目的本来是为了隐藏内部成员,但是客户端却可以对它进行任意操作。这个只读属性在我们的类中打开了一个通道将内部成员的引用暴露给了外部。而我们想要的只读属性,并不是这种可读又可写的属性。

      这就是引用类型的神奇。任何引用类型返回的都是对象的引用地址。当我们将对象的引用地址返回给调用者后,调用者就可以完全无视类的只读属性而直接操作对应地址上的引用类型。

      很明显,我们应当避免类似的这种情况。例如我们为类创建了一个接口并希望所有的使用者遵循,我们一定不会希望使用者获得或者修改类的内部成员。我们有四种策略可以保护类的内部成员不受到这种的威胁:使用值类型,使用不可变类型,通过接口进行功能限制和使用包装器(wrapper)。

      值类型通过接口传递的是本身的拷贝。在客户程序中对拷贝的任何修改都不会反映的类的内部成员上来。客户端可以任意处理值类型的拷贝,这不会带来任何问题。

      不可变类型同样是安全的,一个典型的例子就是System.String类。我们可以返回一个string或者任何其它的不可变类型,因为它们是不可被修改的。客户端的任何操作同样不会影响到类的内部成员的安全。

      第三种方法是定义接口,通过接口客户程序可以使用内部成员的部分功能。当你创建类的时候,可以定义一组包含类中不同功能性的接口。通过暴露这些功能性接口,可以使内部成员暴露最小化。客户程序只能通过接口来获得我们许可的功能,而不是内部成员的全部功能。对应上例中我们可以通过只暴露DataSet类的IListsource接口的方法来避免对dataset的修改。

      对于DataSet来说还有最后一种方法:使用包装器。通过DataViewManager类我们可以获得DataSet中的数据,但可以避免对其进行不必要的操作:

    public class MyBusinessObject
    
文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • .Net研究栏目导航
    网站频道导航