第三章 對象和類型
打好基礎是關鍵!!!
廢話不多說,開始。
3.1 類和結構
類和結構都使用關鍵字New來聲明實例
類中的數據和函數稱為類的成員
在語法上,結構使用關鍵字struct,類用class來聲明
3.2 類
1.數據成員
數據成員是包含類的數據—字段、常量和事件的成員。數據成員可以是靜態數據。類成員總
是實例成員,除非用static進行顯式的聲明。
2.函數成員
(1)方法
1)方法的聲明
有返回值的和沒有返回值的
//有bool類型返回值 public bool IsSquare(Rectangle rect) { return (rect.Height==rect.Width); } //無返回值 public void IsSquare(Rectangle rect) { }
2)調用方法

using System; namespace Wrox { class MainEntryPoint { static void Main() { // Try calling some static functions Console.WriteLine("Pi is " + MathTest.GetPi()); int x = MathTest.GetSquareOf(5); Console.WriteLine("Square of 5 is " + x); // Instantiate at MathTest object MathTest math = new MathTest(); // this is C#'s way of // instantiating a reference type // Call non-static methods math.Value = 30; Console.WriteLine( "Value field of math variable contains " + math.Value); Console.WriteLine("Square of 30 is " + math.GetSquare()); } } // Define a class named MathTest on which we will call a method class MathTest { public int Value; public int GetSquare() { return Value*Value; } public static int GetSquareOf(int x) { return x*x; } public static double GetPi() { return 3.14159; } } }
3)給方法傳遞參數
分兩種:①.引用傳遞,②.值傳遞
區別是看對變量所做的任何改變是否會影響原始對象的值
①.引用傳遞,會,②.值傳遞,不會
在C#中,除非特別說明,所有的參數都通過值來傳遞。對變量所做的任何改變不會影響原始對象的值。
如:
using System;
namespace Wrox
{
class ParameterTest
{
static void SomeFunction(int[] ints, int i)
{
ints[0] = 100;
i = 100;
}
public static int Main()
{
int i = 0;
int[] ints = { 0, 1, 2, 4, 8 };
// Display the original values
Console.WriteLine("i = " + i);
Console.WriteLine("ints[0] = " + ints[0]);
Console.WriteLine("Calling SomeFunction...");
// After this method returns, ints will be changed,
// but i will not
SomeFunction(ints, i);
Console.WriteLine("i = " + i);
Console.WriteLine("ints[0] = " + ints[0]);
return 0;
}
}
}
結果為:
ParameterTest.exe
i=0
ints[0]=0
Calling SomeFunction...
i=0
ints[0]=100
注意,i的值保持不變,而在ints中改變的值在原始數組中也改變了。
4)ref參數
讓方法使用引用傳遞。
對變量所做的任何改變都會影響原始對象的值
SomeFunction(ints, ref i);
5)out參數
該方法的該變量可以不用初始化
static void SomeFunction(out int i)
{
i=100;
}
6)命名參數
參數要按方法的位置順序寫入,或者注明出。推薦注明出,這樣程序更易讀。
string FullName(string firstName, string lastName)
{
return firstName+””+lastName;
}
FullName("John", "Doe");
FullName(lastName:"Doe",firstName:"John");
7)可選參數
int fun(int para1,int para2=0,int para3 = 0)
{}
//para1是必選參數,para2和para3為可選參數
8)方法重載
class ResultDisplayer
{
void DisplayResult(string result)
{
//implementation
}
void DisplayResult(int result)
{
//implementation
}
(2).屬性
屬性(property)的概念是:它是一個方法或一對方法。
在C#中定義屬性,可以使用下面的語法:
public string SomeProperty
{
get
{
return "This is the property value.這就是屬性值。”;
}
set
{
//do whatever needs to be done to set the property.
//設置屬性值的代碼
}
}
1)只讀和只寫屬性
在屬性定義中省略set訪問器,就可以創建只讀屬性。
同樣,在屬性定義中省略get訪問器,就可以創建只寫屬性。
2)屬性的訪問修飾符
屬性可以有公有的get訪問器和私有或受保護的set訪問器。
3)自動實現的屬性
如果屬性的set和get訪問器中沒有任何邏輯,就可以使用自動實現的屬性。
public int Age {get; set;}
這樣的話,必須有兩個訪問器,即不能為只讀,只寫。
但是,每個訪問器的訪問級別可以不同。
public int{get; private set;}
4)內聯
c#代碼編譯的時候自動內聯,不用程序員考慮。
(3).構造函數
1)靜態構造函數
C#可以給類編寫無參數的靜態構造函數。這種構造函數只執行一次,只要創建類的對象,就會執行它。
class MyClass { static MyClass() { //initialization code } //rest of class definition }
編寫靜態構造函數的一個原因是,類有一些靜態字段或屬性,需要在第一次使用類之前,從外部源中初始化這些靜態字段和屬性。
2)從構造函數中調用其他構造函數
構造函數初始化器
class Car private string description; private uint nWheels; public Car(string description, uint nWheels) { this.description=description; this.nWheels=nWheels; } public Car(string description):this(description,4) { }
構造函數初始化器在構造函數的函數體之前執行。
3.只讀字段
readonly關鍵字比const靈活得多,允許把一個字段設置為常量,但還需要執行一些計算,以確定它的初始值。
其規則是可以在構造函數中給只讀字段賦值,但不能在其他地方賦值。
public class DocumentEditor { public static readonly uint MaxDocuments static DocumentEditor() { MaxDocuments=DoSomethingToFindOutMaxNumber(); } }
3.3匿名類型var
var與new關鍵字一起使用時,可以創建匿名類型。
var captain=new{person.FirstName, person.MiddleName, person.LastName};
3.4結構
class 是類,struct是結構
結構不支持繼承。
對於結構構造函數的工作方式有一些區別。尤其是編譯器總是提供一個無參數的默認構造
函數,它是不允許替換的。
使用結構,可以指定字段如何在內存中的布局。
1.結構是值類型
注意,因為結構是值類型,new運算符並不分配堆中的內存,而是只調用相應的構造函數,根據傳送給它的參數,初始化所有的字段。
2.結構和繼承
結構不能從另一個結構中繼承。
3.結構的構造函數
結構不允許定義無參數的構造函數,不能在結構定義中給結構賦值。
3.5 部分類partial
partial關鍵字允許把類、結構或接口放在多個文件中。
//BigClassPart1.cs [CustomAttribute] partial class TheBigClass: TheBigBaseClass, IBigClass { public void MethodOne() { } ) //BigClassPart2.cs [AnotherAttribute] partial class TheBigClass:IOtherBigClass { public void MethodTwo() { } }
編譯后,等價的源文件變成:
[CustomAttribute] [AnotherAttribute] partial class TheBigClass:TheBigBaseClass, IBigClass, IOtherBigClass { public void MethodOne() { } public void MethodTwo() { } }
3.6 靜態類
使用static關鍵字,編譯器可以檢查用戶是否不經意間給該類添加了實例成員。如果是,就生成一個編譯錯誤。這可以確保不創建靜態類的實例。
static class StaticUtilities { public static void HelperMethod() { } }
3.7 Object類
所有的.NET類都派生自Systsm.Object
(1)System.Object()方法
1)ToString()方法
int i=50; string str=i.ToString();
2)GetHashTable()方法
3)Equals()(兩個版本)和ReferenceEquals()方法
4)Finaliz()方法
5)GetType()方法
6)MemberwiseClone()方法
3.8 擴展方法
擴展方法是靜態方法,它是類的一部分,但實際上沒有放在類的源代碼中。假定Money
類需要一個方法AddToAmount(decimal amountToAdd)。但是,由於某種原因,.程序集最初的源代碼
不能直接修改。此時必須做的所有工作就是創建一個靜態類,把方法AddToAmount()添加為一個靜
態方法。對應的代碼如下:
namespace Wrox { public static class MoneyExtension { public static void AddToAmount(this Money money, decimal amountToAdd) { money.Amount+=amountToAdd; } } }
通過這一章把類和結構的大體框架都讀懂了,一些細節還不是很懂,多看程序,多寫代碼慢慢熟悉吧。