首頁 > 軟體

C#中的陣列用法詳解

2022-04-11 19:01:12

如果需要使用同一型別的多個物件,可以使用陣列和集合(後面介紹)。C#用特殊的記號宣告,初始化和使用陣列。Array類在後臺發揮作用,它為陣列中的元素排序和過濾提供了多個方法。使用列舉元,可以迭代陣列中的所有元素。
如果需要使用不同型別的多個物件,可以使用Tuple(元組)型別。

一.簡單陣列(一維陣列)

陣列是一種資料結構,它可以包含同一個型別的多個元素。

1.陣列的宣告

在宣告陣列時,先定義陣列中的元素型別,其後是一對空方括號和一個變數名。

int[] myArray;

2.陣列的初始化

宣告了陣列之後,就必須為陣列分配記憶體,以儲存陣列的所有元素。陣列是參照型別,所以必須給它分配堆上的記憶體。為此,應使用new運運算元,指定陣列中元素的型別和數量來初始化陣列的變數。

myArray = new int[4];

在宣告和初始化陣列後,變數myArray就參照了4個整數值,它們位於託管堆上:

在指定了陣列的大小後,就不能重新設定陣列的大小。如果事先不知道陣列中應包含多少個元素,就可以使用集合。
除了在兩個語句中宣告和初始化陣列之外,還可以在一個語句中宣告和初始化陣列:

int[] myArray = new int[4];

還可以使用陣列初始化器為陣列的每個元素複製。陣列初始化器只能在宣告陣列變數時使用,不能在宣告陣列之後使用。

int[] myArray = new int[4]{1,3,5,7};

如果用花括號初始化陣列,可以不指定陣列的大小,因為編譯器會自動統計元素的個數:

int[] myArray = new int[]{1,3,5,7};

也可以使用更簡單的形式:

int[] myArray = {1,3,5,7};

3.存取陣列元素

在宣告和初始化陣列之後,就可以使用索引器存取其中的元素了。陣列只支援有整型引數的索引器。
索引器總是以0開頭,表示第一個元素。可以傳遞給索引器的最大值是元素個數減1,因為索引從0開始:

int[] myArray = {1,3,5,7};
int v1 = myArray[0];
int v2 = myArray[1];
myArray[3] = 4;

可以使用陣列的Length屬性獲取元素的個數。

4.陣列中使用參照型別

陣列除了能宣告預定義型別的陣列,還可以宣告自定義型別的陣列。

  public class Person
  {
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public override string ToString()
    {
      return String.Format("{0} {1}", FirstName, LastName);
    }
  }

  Person[] myPersons = new Person[2];
  myPersons[0] = new Person { FirstName = "Ayrton", LastName = "Senna" };
  myPersons[1] = new Person { FirstName = "Michael", LastName = "Schumacher" };

如果陣列中的元素是參照型別,就必須為每個陣列元素分配記憶體。如果使用了陣列中未分配記憶體的元素,就會丟擲NullReferenceException型別的異常。
下面是記憶體情況:

對自定義型別也可以使用陣列初始化器:

  Person[] myPersons2 =
  {
    new Person { FirstName="Ayrton", LastName="Senna"},
    new Person { FirstName="Michael", LastName="Schumacher"}
  };

二.多維陣列

多維陣列用兩個或多個整數來索引。
在C#中宣告多維陣列,需要在方括號中加上逗號。陣列在初始化時應指定每一維的大小(也稱為階)。

int[,] twoDim = new int[3,3];
twoDim[0,0] = 1;
twoDim[0,1] = 2;
twoDim[0,2] = 3;
twoDim[1,0] = 4;
twoDim[1,1] = 5;
twoDim[1,2] = 6;
twoDim[2,0] = 7;
twoDim[2,1] = 8;
twoDim[2,2] = 9;

宣告陣列之後,就不能修改其階數了。
也可以使用初始化器來初始化多維陣列:

  int[,] twoDim ={
    {1,2,3},
    {4,5,6},
    {7,8,9}
    };

使用陣列初始化器時,必須初始化陣列的每個元素,不能遺漏任何元素。
宣告一個三位陣列:

  int[,,] threeDim ={
    {{1,2},{3,4}},
    {{5,6},{7,8}},
    {{9,10},{11,12}}
    };
  Console.WriteLine(threeDim[0,1,1]);

三.鋸齒陣列

二維陣列的大小對應於一個矩形,而鋸齒陣列的大小設定比較靈活,在鋸齒陣列中,每一行都可以有不同的大小。
在宣告鋸齒陣列時,要依次放置左右括號。在初始化鋸齒陣列時,只在第一對方括號中設定該陣列包含的行數。定義各行中元素個數的第二個方括號設定為空,因為這類陣列的每一行包含不同的元素個數。之後,為每一行指定行中的元素個數:

  int[][] jagged = new int[3][];
  jagged[0] = new int[2]{1,2};
  jagged[1] = new int[4]{3,4,5,6};
  jagged[2] = new int[3]{7,8};

迭代鋸齒陣列中的所有元素的程式碼可以放在巢狀的for迴圈中。在外層的for迴圈中迭代每一行,在內層的for迴圈中迭代一行中的每個元素:

  for(int row = 0;row<jagged.Length;row++)
  {
    for(int element = 0;element<jagged[row].Length;element++)
    {
      Console.WriteLine("row:{0}, element:{1},value:{2}",row,element,jagged[row][element]);
    }
  }

四.Array類

用方括號宣告陣列是C#中使用Array類的表示法。在後臺使用C#語法,會建立一個派生自抽象基礎類別Array的新類。這樣,就可以使用Array類為每個C#陣列定義的方法和屬性了。
Array類實現的其它屬性有LongLength和Rank。如果陣列包含的元素個數超出了整數的取值範圍,就可以使用LongLength屬性來獲得元素個數。使用Rank屬性可以獲得陣列的維數。

1.建立陣列

Array類是一個抽象類,所以不能使用建構函式來建立陣列。但除了使用C#語法建立陣列範例之外,還可以使用靜態方法CreateInstance()建立陣列。如果事先不知道元素的型別,該靜態方法就很有用,因為型別可以作為Type物件傳遞給CreateInstance()方法。
CreateInstance()方法的第一個引數是元素的型別,第二個引數定義陣列的大小。
可以使用SetValue()方法設定對應元素的值,用GetValue()方法讀取對應元素的值。

  Array intArray1 = Array.CreateInstance(typeof(int), 5);
  for (int i = 0; i < 5; i++)
  {
    intArray1.SetValue(33, i);
  }

  for (int i = 0; i < 5; i++)
  {
    Console.WriteLine(intArray1.GetValue(i));
  }

還可以將已經建立的陣列強制轉換稱宣告為int[]的陣列:

int[] intArray2 = (int[])intArray1;

CreateInstance()方法有許多過載版本,可以建立多維陣列和索引不基於0的陣列。

  //建立一個2X3的二維陣列,第一維基於1,第二維基於10:
  int[] lengths = { 2, 3 };
  int[] lowerBounds = { 1, 10 };
  Array racers = Array.CreateInstance(typeof(Person), lengths, lowerBounds);

  racers.SetValue(new Person { FirstName = "Alain", LastName = "Prost" }, index1: 1, index2: 10);
  racers.SetValue(new Person
  {
    FirstName = "Emerson",
    LastName = "Fittipaldi"
  }, 1, 11);
  racers.SetValue(new Person { FirstName = "Ayrton", LastName = "Senna" }, 1, 12);
  racers.SetValue(new Person { FirstName = "Michael", LastName = "Schumacher" }, 2, 10);
  racers.SetValue(new Person { FirstName = "Fernando", LastName = "Alonso" }, 2, 11);
  racers.SetValue(new Person { FirstName = "Jenson", LastName = "Button" }, 2, 12);

  Person[,] racers2 = (Person[,])racers;
  Person first = racers2[1, 10];
  Person last = racers2[2, 12];

2.複製陣列

因為陣列是參照型別,所以將一個陣列變數賦予另一個陣列變數,就會得到兩個參照同一陣列的變數。
陣列實現ICloneable介面。這個介面定義的Clone()方法會複製陣列,建立陣列的淺表副本。
如果陣列的元素是值型別,Clone()方法會複製所有值:

  int[] a1 = {1,2};
  int[] a2 = (int[])a1.Clone();

如果陣列包含參照型別,只複製參照。
除了使用Clone()方法之外,還可以使用Array.Copy()方法建立淺表副本。

  Person[] beatles = {
    new Person { FirstName="John", LastName="Lennon" },
    new Person { FirstName="Paul", LastName="McCartney" }
  };

  Person[] beatlesClone = (Person[])beatles.Clone();
  Person[] beatlesClone2 = new Person[2];
  Array.Copy(beatlesClone,beatlesClone2,2);//注意與Clone的語法區別,Copy需要傳遞階數相同的已有陣列。(還可以使用CopyTo()方法)

3.排序

Array類使用快速排序演演算法對陣列中的元素進行排序。Sort()方法需要陣列中的元素實現IComparable介面。因為簡單型別(如String,Int32)實現IComparable介面,所以可以對包含這些型別的元素排序。

    string[] names = {
    "Christina Aguilera",
    "Shakira",
    "Beyonce",
    "Gwen Stefani"
    };

    Array.Sort(names);

    foreach (string name in names)
    {
      Console.WriteLine(name);
    }

如果對陣列使用使用自定義類,就必須實現IComparable介面。這個介面只定義了一個方法CompareTo()方法,如果要比較的物件相等,該方法就返回0.如果該範例應排在引數物件的前面,該方法就返回小於i0de值。如果該範例應排在引數物件的後面,該方法就返回大於0的值。

  public class Person : IComparable<Person>
  {
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public override string ToString()
    {
      return String.Format("{0} {1}",
      FirstName, LastName);
    }

    public int CompareTo(Person other)
    {
      if (other == null) throw new ArgumentNullException("other");

      int result = this.LastName.CompareTo(other.LastName);
      if (result == 0)
      {
        result = this.FirstName.CompareTo(other.FirstName);
      }

      return result;
    }
  }

使用者端程式碼:

  Person[] persons = {
  new Person { FirstName="Damon", LastName="Hill" },
  new Person { FirstName="Niki", LastName="Lauda" },
  new Person { FirstName="Ayrton", LastName="Senna" },
  new Person { FirstName="Graham", LastName="Hill" }
  };
  Array.Sort(persons);
  foreach (Person p in persons)
  {
    Console.WriteLine(p);
  }

如果Person物件的排序方式與上述不同,或者不能修改在陣列中用作元素的類,就可以實現IComparer介面或IComparer<T>介面。這兩個介面定義了方法Compare()方法。機型比較的類必須實現這兩個介面之一。

  public enum PersonCompareType
  {
    FirstName,
    LastName
  }
  //通過使用實現了IComparer<T> 泛型介面的PersonComparer類比較Person物件陣列。
  public class PersonComparer : IComparer<Person>
  {
    private PersonCompareType compareType;

    public PersonComparer(PersonCompareType compareType)
    {
      this.compareType = compareType;
    }


    #region IComparer<Person> Members

    public int Compare(Person x, Person y)
    {
        if (x == null) throw new ArgumentNullException("x");
        if (y == null) throw new ArgumentNullException("y");

      switch (compareType)
      {
        case PersonCompareType.FirstName:
          return x.FirstName.CompareTo(y.FirstName);
        case PersonCompareType.LastName:
          return x.LastName.CompareTo(y.LastName);
        default:
          throw new ArgumentException(
          "unexpected compare type");
      }
    }

    #endregion
  }

使用者端程式碼:

  Person[] persons = {
  new Person { FirstName="Damon", LastName="Hill" },
  new Person { FirstName="Niki", LastName="Lauda" },
  new Person { FirstName="Ayrton", LastName="Senna" },
  new Person { FirstName="Graham", LastName="Hill" }
  };
  Array.Sort(persons,
  new PersonComparer(PersonCompareType.FirstName));

  foreach (Person p in persons)
  {
    Console.WriteLine(p);
  }

五.陣列作為引數

陣列可以作為引數傳遞給方法,也可以從方法中返回。

1.陣列協變

陣列支援協變。這表示陣列可以宣告為基礎類別,其派生型別的元素可以賦值於陣列元素。

  static void DisPlay(object[] o)
  {
    //..
  }

可以給該方法傳遞一個Person[]。
陣列協變只能用於參照型別,不能用於值型別。

2.ArraySegment<T>

結構ArraySegment<T>表示陣列的一段。如果需要使用不同的方法處理某個大型陣列的不同部分,那麼可以把相應的陣列部分複製到各個方法。
ArraySegment<T>結構包含了關於陣列段的資訊(偏移量和元素個數)。

  static void Main()
  {
    int[] ar1 = { 1, 4, 5, 11, 13, 18 };
    int[] ar2 = { 3, 4, 5, 18, 21, 27, 33 };
    var segments = new ArraySegment<int>[2]
    {
      new ArraySegment<int>(ar1, 0, 3),
      new ArraySegment<int>(ar2, 3, 3)
    };


    var sum = SumOfSegments(segments);
    Console.WriteLine("sum of all segments: {0}", sum);

  }

  static int SumOfSegments(ArraySegment<int>[] segments)
  {
  int sum = 0;
  foreach (var segment in segments)
  {
    for (int i = segment.Offset; i < segment.Offset + segment.Count; i++)
    {
        sum += segment.Array[i];
    }

  }
  return sum;
  }

陣列段不復制原陣列的元素,但原陣列可以通過ArraySegment<T>存取。如果陣列段中的元素改變了,這些變化就會反映到原陣列中。

六.列舉集合

在foreach語句中使用列舉,可以迭代集合中的元素,且無需知道集合中元素的個數。foreach語句使用一個列舉元。foreach會呼叫實現了IEnumerable介面的集合類中的GetEumerator()方法。GetEumerator()方法返回一個實現IEnumerator介面的物件列舉。foreach語句就可以使用IEnumerable介面迭代集合了。
GetEumerator()方法在IEnumerable介面中定義。

1.IEnumerator介面

foreach語句使用IEnumerator介面的方法和屬性,迭代集合中所有元素。IEnumerator介面定義了Current屬性,來返回遊標所在的元素,該介面的MoveNext()方法移動到集合的下一個元素上,如果有這個元素,該方法就返回true。如果集合不再有更多的元素,該方法就返回false.
這個介面的泛型版本IEnumerator<T>派生自介面IDisposable,因此定義了Dispose()方法,來清理列舉元佔用的資源。

2.foreach語句

C#中foreach語句不會解析為IL程式碼中的foreach語句。C#編譯器會把foreach語句轉換為IEnumerator介面的方法和屬性。

  Person[] persons = {
    new Person { FirstName="Damon", LastName="Hill" },
    new Person { FirstName="Niki", LastName="Lauda" },
    new Person { FirstName="Ayrton", LastName="Senna" },
    new Person { FirstName="Graham", LastName="Hill" }
  };
  foreach (Person p in persons)
  {
    Console.WriteLine(p);
  }

foreach語句會解析為下面的程式碼:

  IEnumerator<Person> enumerator = persons.GetEumerator();
  while(enumerator.MoveNext())
  {
    Person p = enumerator.Current;
    Console.WriteLine(p);
  }

3.yield語句

在C#2.0之前,foreach語句可以輕鬆的迭代集合,但建立列舉元需要做大量的工作。C#2.0新增了yield語句,以便建立列舉元。
yield return 語句返回集合的一個元素,並移動到下一個元素。yield break可停止迭代。
下面的例子實現返回兩個字串:

  public class HelloCollection
  {
    public IEnumerator<string> GetEnumerator()
    {
    yield return "Hello";
    yield return "World";
    }
  }

使用者端程式碼:

  var helloCollection = new HelloCollection();
  foreach (string s in helloCollection)
  {
    Console.WriteLine(s);
  }

包含yield語句的方法或屬性也稱為迭代塊。迭代塊必須宣告為返回IEnumerator或IEnumerable介面,或者這些介面的泛型版本。這個塊可以包含多條yield return語句或yield break語句,但不能包含return語句。
使用迭代塊,編譯器會生成一個yield型別,其中包含一個狀態機,如下面程式碼所示:
yield型別實現IEnumerator和IDisposable介面的方法和屬性。下面的例子可以把yield型別看作內部類Enumerator。外部類的GetEnumerator()方法範例化並返回一個新的yield型別。在yield型別中,變數state定義了迭代的當前位置,每次呼叫MoveNext()時,當前位置都會改變。MoveNext()封裝了迭代塊的程式碼,並設定了current變數的值,從而使Current屬性根據位置返回一個物件。

  public class HelloCollection
  {
    public IEnumerator<string> GetEnumerator()
    {
      return new Enumerator(0);
    }

  public class Enumerator:IEnumerator<string>,IEnumerator,IDisposable
  {
    private int state;
    private string current;

    public Enumerator(int state)
    {
      this.state = state;
    }

    bool System.Collections.IEnumerator.MoveNext()
    {
      switch(state)
      {
        case 0:
          current="hello";
          state =1;
          return true;
        case 1:
          current="world";
          state =2;
          return true;
        case 2:
          break;
      }

      return false;
    }

    void System.Collection>IEnumerator.Reset()
    {
      throw new NotSupportedException();
    }

    string System.Collections.Generic.IEnumerator<string>.Current
    {
      get
      {
        return current;
      }
    }

    object System.Collections.IEnumerator.Current
    {
      get
      {
        return current;
      }
    }

    void IDisposable.Dispose()
    {}
  }
}

yield語句會產生一個列舉元,而不僅僅生成一個包含的項的列表。這個列舉元通過foreach語句呼叫。從foreach中依次存取每一項,就會存取列舉元。這樣就可以迭代大量的資料,而無需一次把所有的資料都讀入記憶體。

(1).迭代集合的不同方式

可以使用yield return語句,以不同方式迭代集合。
類MusicTitles可以用預設方式通過GetEnumerator()方法迭代標題,該方法不必在程式碼中編寫,也可以用Reverse()逆序迭代標題,用Subset()方法迭代子集合:

    public class MusicTitles
    {
      string[] names = {
      "Tubular Bells", "Hergest Ridge",
      "Ommadawn", "Platinum" };

      public IEnumerator<string> GetEnumerator()
      {
        for (int i = 0; i < 4; i++)
        {
          yield return names[i];
        }
      }

      public IEnumerable<string> Reverse()
      {
        for (int i = 3; i >= 0; i--)
        {
          yield return names[i];
        }
      }

      public IEnumerable<string> Subset(int index, int length)
      {
        for (int i = index; i < index + length;i++)
        {
          yield return names[i];
        }
      }
    }

使用者端程式碼:

    var titles = new MusicTitles();
    foreach (var title in titles)
    {
      Console.WriteLine(title);
    }
    Console.WriteLine();

    Console.WriteLine("reverse");
    foreach (var title in titles.Reverse())
    {
      Console.WriteLine(title);
    }
    Console.WriteLine();

    Console.WriteLine("subset");
    foreach (var title in titles.Subset(2, 2))
    {
      Console.WriteLine(title);
    }

(2).用yield return 返回列舉元

public class GameMoves
  {
    private IEnumerator cross;
    private IEnumerator circle;

    public GameMoves()
    {
      cross = Cross();
      circle = Circle();
    }

    private int move = 0;
    const int MaxMoves = 9;

    public IEnumerator Cross()
    {
      while (true)
      {
        Console.WriteLine("Cross, move {0}", move);
        if (++move >= MaxMoves)
          yield break;
        yield return circle;
      }
    }

    public IEnumerator Circle()
    {
      while (true)
      {
        Console.WriteLine("Circle, move {0}", move);
        if (++move >= MaxMoves)
          yield break;
        yield return cross;
      }
    }
  }

使用者端程式碼:

    var game = new GameMoves();

    IEnumerator enumerator = game.Cross();
    while (enumerator.MoveNext())
    {
      enumerator = enumerator.Current as IEnumerator;
    }

這樣會交替呼叫Cross()和Circle()方法。

七.元組(Tuple)

元組可以合併不同型別的物件。元組起源於函式程式語言,如F#。在.NET Framework中,元組可用於所有的.Net語言。
.NET Framework定義了8個泛型Tuple類和一個靜態Tuple類,它們用作元組的工廠。不同的泛型Tuple類支援不同數量的元素。如,Tuple<T1>包含一個元素,Tuple<T1,T2>包含兩個元素。

Tuple<string, string> name = new Tuple<string, string>("Jochen", "Rindt");

元組也可以用靜態Tuple類的靜態Create()方法建立。Create()方法的泛型引數定了要範例化的元組型別:

  public static Tuple<int, int> Divide(int dividend, int divisor)
  {
    int result = dividend / divisor;
    int reminder = dividend % divisor;

    return Tuple.Create<int, int>(result, reminder);
  }

可以用屬性Item1和Item2存取元組的項:

  var result = Divide(5, 2);
  Console.WriteLine("result of division: {0}, reminder: {1}", result.Item1, result.Item2);

如果元組包含的項超過8個,就可以使用帶8個引數的Tuple類定義。最後一個模板引數是TRest,表示必須給它傳遞一個元組。這樣,就可以建立帶任意個引數的元組了。
 

  var tuple = Tuple.Create<string, string, string, int, int, int, double, Tuple<int, int>>(
  "Stephanie", "Alina", "Nagel", 2009, 6, 2, 1.37, Tuple.Create<int, int>(52, 3490));

八.結構比較

陣列和元組都實現介面IStructuralEquatable和IStructuralComparable。這兩個介面不僅可以比較參照,還可以比較內容。這些介面都是顯式實現的,所以在使用時需要把陣列和元組強制轉換為這個介面。
IStructuralEquatable介面用於比較兩個元組或陣列是否有相同的內同,IStructuralComparable介面用於給元組或陣列排序。
IStructuralEquatable介面範例:
編寫實現IEquatable介面的Person類,IEquatable介面定義了一個強型別化的Equals()方法,比較FirstName和LastName的值:

public class Person : IEquatable<Person>
  {
    public int Id { get; private set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public override string ToString()
    {
      return String.Format("{0}, {1} {2}", Id, FirstName, LastName);
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return base.Equals(obj);
        return Equals(obj as Person);
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

    #region IEquatable<Person> Members

    public bool Equals(Person other)
    {
      if (other == null)
        return base.Equals(other);

      return this.FirstName == other.FirstName && this.LastName == other.LastName;
    }

    #endregion
  }

建立兩個包含相同內容的Person型別的陣列:

  var janet = new Person { FirstName = "Janet", LastName = "Jackson" };
  Person[] persons1 = { new Person { FirstName = "Michael", LastName = "Jackson" }, janet };
  Person[] persons2 = { new Person { FirstName = "Michael", LastName = "Jackson" }, janet };

由於兩個變數參照兩個不同陣列,所以!=返回True:

  if (persons1 != persons2)
    Console.WriteLine("not the same reference");

對於IStructuralEquatable介面定義的Equals方法,第一個引數是object型別,第二個引數是IEqualityComparer型別。呼叫這個方法時,通過傳遞一個實現了EqualityComparer<T>的物件,就可以定義如何進行比較。通過EqualityComparer<T>類完成IEqualityComparer的一個預設實現。這個實現檢查T型別是否實現了IEquatable介面,並呼叫IEquatable.Equals()方法。如果該類沒有實現IEquatable介面,就呼叫Object基礎類別中Equals()方法:

  if ((persons1 as IStructuralEquatable).Equals(persons2, EqualityComparer<Person>.Default))
  {
    Console.WriteLine("the same content");
  }

元組範例:
Tuple<>類提供了兩個Epuals()方法:一個重寫了Object基礎類別中的Epuals方法,並把object作為引數,第二個由IStructuralEquatable介面定義,並把object和IEqualityComparer作為引數。

  var t1 = Tuple.Create<int, string>(1, "Stephanie");
  var t2 = Tuple.Create<int, string>(1, "Stephanie");
  if (t1 != t2)
  Console.WriteLine("not the same reference to the tuple");

這個方法使用EqualityComparer<object>.Default獲取一個ObjectEqualityComparer<object>,以進行比較。這樣就會呼叫Object.Equals()方法比較元組的每一項:

  if (t1.Equals(t2))
    Console.WriteLine("equals returns true");

還可以使用TupleComparer類建立一個自定義的IEqualityComparer

  TupleComparer tc = new TupleComparer();

  if ((t1 as IStructuralEquatable).Equals(t2, tc))
  {
    Console.WriteLine("yes, using TubpleComparer");
  }


  class TupleComparer : IEqualityComparer
  {
    #region IEqualityComparer Members

    public new bool Equals(object x, object y)
    {
      bool result = x.Equals(y);
      return result;
    }

    public int GetHashCode(object obj)
    {
      return obj.GetHashCode();
    }

    #endregion
  }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com