ASP.NET Lab

The Best Web, The Best Future

博客园 首页 新随笔 订阅 管理

关于数组与数组用法的常规描述,请参考:[Arrays]与[System.Array 类]。

数组 VS 集合

类库设计者可能需要在何时应该使用一个数组而何时又应该返回一个集合之间作出困难的决定。虽然这些类型有着相似的用法模型,但是它们还是存在着不同的性能特征。通常,你应该在执行 Add、Remove,或者其他被支持的数组操作方法的时候使用一个集合。

关于使用集合的更多信息,请参考:[集合与数据结构]。

数组的用法

不要返回数组的一个内部实例。这样做会允许调用代码来改变数组的内容。下列范例示范了数组 badChars 如何才能够通过任何访问 Path 属性的代码而被改变,即使这个属性并没有实现设置访问器。

Visual Basic
Imports System
Imports System.Collections
Imports Microsoft.VisualBasic

Public Class ExampleClass
   NotInheritable Public Class Path
      Private Sub New()
      End Sub

      Private Shared badChars() As Char = {Chr(34),"<"c,">"c}
      
      Public Shared Function GetInvalidPathChars() As Char()
         Return badChars
      End Function

   End Class
   
   Public Shared Sub Main()
      ' 下列代码显示了数组中的元素是被期望的。
      Dim c As Char
      For Each c In  Path.GetInvalidPathChars()
         Console.Write(c)
      Next c
      Console.WriteLine()
      
      ' 下列代码把所有的值都设置成了字母 A。
      Path.GetInvalidPathChars()(0) = "A"c
      Path.GetInvalidPathChars()(1) = "A"c
      Path.GetInvalidPathChars()(2) = "A"c
      
      ' 下列代码在控制台中显示数组的元素。注意:这些值已经被改变。
      For Each c In  Path.GetInvalidPathChars()
         Console.Write(c)
      Next c
   End Sub
End Class
C#
using System;
using System.Collections;

public class ExampleClass
{
   public sealed class Path
   {
      private Path(){}
      private static char[] badChars = {'\"', '<', '>'};
      public static char[] GetInvalidPathChars()
      {
         return badChars;
      }
   }
   public static void Main()
   {
      // 下列代码显示了数组中的元素是被期望的。
      foreach(char c in Path.GetInvalidPathChars())
      {
         Console.Write(c);
      }
      Console.WriteLine();

      // 下列代码把所有的值都设置成了字母 A。
      Path.GetInvalidPathChars()[0] = 'A';
      Path.GetInvalidPathChars()[1] = 'A';
      Path.GetInvalidPathChars()[2] = 'A';

      // 下列代码在控制台中显示数组的元素。注意:这些值已经被改变。
      foreach(char c in Path.GetInvalidPathChars())
      {
         Console.Write(c);
      }
   }
}

你不能够在前面的范例中通过使用 readonly(在 Visual Basic 中是 ReadOnly)的 badChars 数组来纠正这个问题。但是你可以对 badChars 数组进行复制并且返回被复制的数组,不过这样做存在着重要的性能牵连。关于详细内容,请参考本文中的稍后部分:[返回数组的属性]。下列代码范例示范了如何更改 GetInvalidPathChars 方法来返回 badChars 数组的一个复制。

Visual Basic
Public Shared Function GetInvalidPathChars() As Char()
   Return CType(badChars.Clone(), Char())
End Function
C#
public static char[] GetInvalidPathChars()
{
   return (char[])badChars.Clone();
}

返回数组的属性

你应该使用集合来避免通过返回数组的属性而导致的低效代码。在下列代码范例中,对于 myObj 属性的每一次调用都会创建该数组的一个复制。结果,这个数组的 2n+1 个复制将在下列循环中被创建。

Visual Basic
Dim i As Integer
For i = 0 To obj.myObj.Count - 1
   DoSomething(obj.myObj(i))
Next i
C#
for (int i = 0; i < obj.myObj.Count; i++)
      DoSomething(obj.myObj[i]);

关于更多信息,请参考:[属性与方法之间的选择]。

返回数组的字段

不要使用 readonly(在 Visual Basic 中是 ReadOnly)数组字段。如果这样做,这个数组就将是只读的并且不能够被改变,但是数组中的元素却能够被改变。下列代码范例示范了只读数组 InvalidPathChars 中的元素是如何被改变的。

C#
public sealed class Path
{
   private Path(){}
   public static readonly char[] InvalidPathChars = {'\"', '<', '>','|'}'
}
//下列代码能够被用来改变数组中的值。
Path.InvalidPathChars[0] = 'A';

在集合中使用被索引的属性

使用被索引的属性只能够作为集合类或者接口的默认成员。不要在非集合类型中创建功能家族。一种方法的模式(如 Add、Item,以及 Count)能够表示这个类型应该是一个集合。

返回空数组

String 与 Array 属性应该从来都不返回一个 null 引用。因为在这些环境中的 null 值是难以理解的。例如,一个用户可能会假设下列代码将会正常运作。

Visual Basic
Public Sub DoSomething()
   Dim s As String = SomeOtherFunc()
   If s.Length > 0 Then
      ' 在这里做些什么。
   End If
End Sub
C#
public void DoSomething()
{
   string s = SomeOtherFunc();
   if (s.Length > 0)
   {
      // 在这里做些什么。
   }
}

一般的规则是:null 值、空字符串(""),以及空数组(0 个子项的数组)都应该被视为同一种方式。并且返回一个空数组来替代一个 null 引用。

posted on 2007-02-03 20:44  Laeb  阅读(1533)  评论(0编辑  收藏  举报