第一部分
一.訪問關鍵字:base,this
base:訪問基類的成員,用於從派生類中訪問基類的成員,
1.調用基類上已經被重寫的方法。
2.指定創建派生類實例時應調用的基類構造函數。
(對基類的訪問只能在派生類的構造函數實例的方法和實例的屬性訪問器中)
屬性訪問器:get,set函數。不能在靜態方法中使用base關鍵字。
例:
在子類的方法中寫 base.GetInfo();調用基類的方法。
基類中的構造函數重載了,Mybase()和Mybase(int i);
在子類的構造函數中public MyDerived():base(int i)
public MyDerived(int i):base()
this:引用當前對象。用於引用為其調用方法的當前實例,靜態成員函數沒有this指針。可以用於從構造函數、實例方法、實例訪問器中訪問成員。
1.限定被相似的名子隱藏的成員
public void A(int a, int b )
{
this.a=a;
this.b=b;
}
2.將對象作為參數傳遞到函數中
public void ShowInstance()
{
print(this);
console.writeline("lalalalllalalala");
}
3.聲明索引器
public int this[int param]
{
get{ return array[param]; }
set{ array[param]=value; }
}
二.轉換關鍵字:explicit, implicit, operator
explicit:用於聲明用戶定義的顯式類型轉換運算符。
例:
class MyType
{
public static explicit operator MyType(int i) //從int顯式轉換成MyType類型的代碼!!!
}
顯式類型轉換符必須通過類型轉換調用。需要在轉換失敗時拋出異常。
if(轉換失敗的條件)
throw new ArgumentException();
int i;
MyType x = (MyType)i;
注意!!!!!!!如果轉換可能導致信息丟失,則使用explicit關鍵字。
implicit:用於聲明用戶定義的 隱式類型轉換運算符。
例:
class MyType
{
public static implicit operator int(MyType i) //從MyType隱式轉換成Mint類型的代碼!!!
}
MyType i;
int x = i;
注意!!!!!!!!!!!由於隱式轉換在程序員未指定的情況下發生,所以必須防止出現不良的后果。只有在一定不會出現異常和信息丟失時才可以使用implicit,否則使用expicit。
operator:用於聲明用戶在類或結構中自定義的運算符。有四種形式:
public static 結果類型 operator unary-operator (參數類型 參數名)
public static implict operator 目標類型 (輸入類型 參數名)
public static explict operator 目標類型 (輸入類型 參數名)
//implict中,目標類型一般是封閉類型,例如:int, double, byte等。
//explict中,目標類型一般是自定義類型,例如:MyType等。
三.文字關鍵字:null,false,true
null:表示不引用任何對象的空引用的值。null是引用類型的默認值。
true:用戶自定義的類型可以重載true運算符,用來表示是否滿足條件,若滿足則返回bool值的true,否則返回false。
注意!!!!!!!若在自定義類型中定義了true運算符,則必須定義false運算符。
true文字值:表示bool的真。
false:false運算符:用戶自定義的類型可以重載false運算符,用來表示是否滿足條件,若不滿足則返回bool值的true,否則返回false。
注意!!!!!!!若在自定義類型中定義了false運算符,則必須定義true運算符。
false文字值:表示bool的假。
(true和false運算符可以用在任何條件判斷中。)
四.方法參數關鍵字:params,ref,out
params:用於指定在參數數目可變處,采用參數的方法參數。只能有一個params,並且在他后面不能再有參數。
方法參數:如果在為方法聲明參數時未使用 ref 或 out,則該參數可以具有關聯的值。可以在方法中更改該值,但當控制傳遞回調用過程時,不會保留更改的值
using System;
public class MyClass
{
public static void UseParams(params int[] list)
{
for (int i = 0 ; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
Console.WriteLine();
}
public static void UseParams2(params object[] list)
{
for (int i = 0 ; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
Console.WriteLine();
}
static void Main()
{
UseParams(1, 2, 3);
UseParams2(1, 'a', "test");
//An array of objects can also be passed, as long as
// the array type matches the method being called.
int[] myarray = new int[3] {10,11,12};
UseParams(myarray);
}
輸出
1
2
3
1
a
test
10
11
12
//把1,2,3三個參數當成一個數組處理,在最后輸出Console.WriteLine();
ref:使方法可以引用傳遞到該方法的參數。當程序跳轉到調用方法處的時候,在方法中對參數所做的任何改動都將傳遞給參數。類似於傳地址。
注意!!!!!必須將參數作為ref參數 顯示 的傳遞到方法。參數必須顯示的初始化!屬性不是變量不能作為ref參數傳遞。
例子:
using System;
using System.Collections.Generic;
using System.Text;
namespace 真的是關鍵字
{
class Program
{
public static void TestRef(ref string i)
{
i = "change once!";
}
public static void TestNoRef(string i)
{
i = "change twice!";
}
static void Main(string[] args)
{
string i = "begining!";
Console.WriteLine(i);
TestRef(ref i);
Console.WriteLine(i);
TestNoRef(i);
Console.WriteLine(i);
Console.ReadLine();
}
}
}輸出:beginning!
Change once!
Change once!
out:使方法可以引用傳遞到該方法的同一個變量。當程序跳轉到方法調用處時,在方法中對變量所做的任何改動都將傳遞給該變量。
注意!!!!!當希望方法返回多個值時,聲明out非常有用。
一個方法可以有多個out參數。
必須將參數作為out參數顯示的傳遞到方法。
不必初始化作為out參數的變量。
屬性不是變量不能作為out變量。
注意!!!!!ref參數必須顯示初始化,而out參數不用。
例子:
using System;
using System.Collections.Generic;
using System.Text;
namespace 真的是關鍵字
{
class Program
{
public static int TestOut(out string i)
{
i = "change once!";
return -1;
}
static void Main(string[] args)
{
string i = "begining!";
Console.WriteLine(i);
Console.WriteLine(TestOut(out i));
Console.WriteLine(i);
Console.ReadLine();
}
}
}
5.修飾關鍵字
修飾符 作用
訪問修飾符
Public
Private
Internal
protected 指定聲明的類型和成員的可訪問性
abstract 指示某個類只能是其他類的基類,虛基類。
Const 指定無法修改字段或局部變量的值,只能在聲明時初始化。
Event 聲明一個事件
Extern 指示外部實現此方法
Override 提供從基類繼承的 虛擬成員 的新實現
Readonly 聲明的字段只能在聲明時或構造函數中初始化。
Sealed 指定該類不能被繼承
Static 聲明對象屬於類本身不屬於特定的對象。
Unsafe 聲明不安全的上下文
Virtual 在派生類中實現具體方法,可以重寫。
Volatile 指示字段可以由操作系統,硬件或並發的線程等在程序中修改。
1.訪問關鍵字
聲明的可訪問性 意義
public 訪問不受限制
Protected 訪問僅限於包含類或從包含類派生的類
Internal 訪問僅限於當前項目
Protected internal 訪問僅限於包含類或從包含類派生的當前項目和類
Private 訪問僅限於包含類
不嵌套在其他類型中的頂級類型只能有public和internal可訪問性,默認是internal。
類型 默認的成員可訪問性 允許的訪問性
枚舉 Public 無(internal)
Public
Protected
類 Private Internal
Private
Protected internal
接口 Public 無(internal)
Public
結構 Private Internal
Private
嵌套類型的可訪問性取決於它的可訪問域,而且不能超出包含它類型的可訪問域。
2.可訪問域
1.~~~~可訪問域:用於指定程序段中可以引用該成員的位置。如果是嵌套類型,那么它的可訪問域由成員的訪問級別和直接包含該成員的類型的可訪問域共同決定。
using System;
using System.Collections.Generic;
using System.Text;
namespace 真的是關鍵字
{
public class T1
{
public static int publicInt;
internal static int internalInt;
private static int privateInt = 0; // CS0414
public class M1
{
public static int publicInt;
internal static int internalInt;
private static int privateInt = 0; // CS0414
}
private class M2
{
public static int publicInt = 0;
internal static int internalInt = 0;
private static int privateInt = 0; // CS0414
}
}
class MainClass
{
static void Main()
{
// Access is unlimited:
T1.publicInt = 1;
// Accessible only in current assembly:
T1.internalInt = 2;
// Error: inaccessible outside T1:
// T1.myPrivateInt = 3;
// Access is unlimited:
T1.M1.publicInt = 1;
// Accessible only in current assembly:
T1.M1.internalInt = 2;
// Error: inaccessible outside M1:
// T1.M1.myPrivateInt = 3;
// Error: inaccessible outside T1:
// T1.M2.myPublicInt = 1;
// Error: inaccessible outside T1:
// T1.M2.myInternalInt = 2;
// Error: inaccessible outside M2:
// T1.M2.myPrivateInt = 3;
}
}
}
3.對使用可訪問性級別的限制
1~~~~基類的可訪問性必須不小於派生類。
2~~~~派生類的可訪問性必須不大於基類。
3~~~~成員的可訪問性至少是包含它的類。
例子:
Class BaseClass{};
Public class MyClass: BaseClass{};
這是錯誤的!!!!!!!!!!!!!!!!
對使用聲明的而訪問型級別限制
上下文 備注
類 類類型的直接基類必須至少與類類型本身具有同樣的可訪問性。
接口 接口類型的顯式基類接口必須至少與接口類型具有同樣的可訪問性。
委托 返回類型和參數類型必須至少與委托本身具有同樣的可訪問性。
方法 返回類型和參數類型必須至少與方法本身具有同樣的可訪問性。
運算符 返回類型和參數類型必須至少與運算符本身具有同樣的可訪問性。
構造函數 它的參數必須至少與構造函數本身具有同樣的可訪問性。
字段(它是包含在類或結構中的對象或值) 字段的可訪問性必須至少與字段本身具有同樣的可訪問性。
4.訪問修飾關鍵字
1~~~~internal:是類型和類型成員的訪問修飾符,只有在同一個程序集中才可以訪問。
通俗的說就是:如果用internal修飾,那么只能在定義它的.cs文件中訪問它。在別的文件中訪問就會出錯。
5.其它修飾關鍵字
1~~~~abstract:可用來修飾 類,方法和屬性。
(1) 在類的聲明中使用abstract,表示這個類只能作為其他類的基類,即抽象類。
抽象類的特點:
a.抽象類不能實例化。
b.抽象類可以包含抽象方法和抽象訪問器。
c.不能用sealed修飾抽象類,否則,該類不能被繼承。
d.從抽象類派生的非抽象類必須包含繼承來的所有抽象方法和抽象訪問器的實實現。
(2) 在方法和屬性中使用abstract,表示此方法或屬性 不包含實現。即抽象方法和抽象屬性。
抽象方法的特點:
A. 抽象方法是隱式的virtual方法。
B. 只允許在抽象類中定義抽象方法。
C. 抽象方法不提供實現,所以沒有方法體。 格式如下:沒有{}!!!!
Public abstract void MyMethod();
D. 實現由重寫方法提供,他是非抽象的。
E. 抽象方法中使用virtual, static, override關鍵字是錯誤的。
F. 靜態屬性上不能使用abstract關鍵字。
G. 在派生類中,通過使用override 可以重寫抽象的繼承屬性。
H. 抽象類必須為所有接口成員提供實現,或將其映射到抽象方法上去。
// abstract_keyword.cs
// Abstract Classes
using System;
abstract class BaseClass // Abstract class
{
protected int _x = 100;
protected int _y = 150;
public abstract void AbstractMethod(); //Abstract method
public abstract int X { get; }
//abstract property
public abstract int Y { get; }
}
class DerivedClass : BaseClass
{
public override void AbstractMethod()
{
_x++;
_y++;
}
}
public override int X // overriding property
{
get
{
return _x + 10;
}
public override int Y // overriding property
{
get
{
return _y + 10;
}
}
static void Main()
{
DerivedClass o = new DerivedClass();
o.AbstractMethod();
Console.WriteLine("x = {0}, y = {1}", o.X, o.Y);
}
}
輸出
x = 111, y = 161
2.~~~~const:用來指定字段或局部變量的之不能被修改。
Public const int a=1,b=2;
3.~~~~event:用於指定一個事件。
指定當代碼中的某些事件發生時調用的委托。此委托可以有一個或多個相關聯的方法。
創建事件的步驟:
1. 創建或標示一個委托。先有委托后定義事件。
2. 創建一個類,其中包含:
A. 委托創建的事件。
B. 調用此事件的方法。
3. 定義將方法連接到事件的類。
4. 使用事件:創建包含事件聲明類的對象。
4~~~~extern:表示方法在外部實現。
注意!!!!!不能將extern和abstract一起使用。
格式舉例:public static extern int MyMethod (int x); 沒有{}
5~~~~override:用於修改方法和屬性,通過 override 聲明重寫的方法稱為重寫基方法。重寫的基方法必須與 override 方法具有相同的簽名。
重寫基方法:有重寫聲明的方法。
注意!!!!!不能重寫非虛方法或靜態方法。
不能使用以下關鍵字修飾重寫方法:new,static,virtual,abstract
重寫的屬性與重寫的方法的要求是一樣的。
重寫的方法中可以調用基類的原來的virtual方法。
namespace 真的是關鍵字
{
public class Square
{
public double x;
public Square(double x)
{
this.x = x;
}
public virtual double Area()
{
return (x*x);
}
}
class Cube : Square
{
public Cube(double x):base(x)
{
}
public override double Area()
{
return (6*base.Area());//調用base即基類的方法。
}
}
class MainClass
{
static void Main()
{
double x = 5.2;
Square s = new Square(x);
Square c = new Cube(x);
Console.WriteLine("Area of Square is{0:F2}",s.Area());
Console.WriteLine("Area of Cube is {0:F2}", c.Area());
Console.ReadLine();
}
}
}
6.~~~~readonly:只可以使用在字段上,被readonly修飾的字段的賦值只能作為 聲明的一部分或者在構造函數中。
1.在聲明中初始化:public readonly double a=1.1;
2.在構造函數中。
readonly 關鍵字與 const 關鍵字不同:const 字段只能在該字段的聲明中初始化。readonly段可以在聲明或構造函數中初始化。因此,根據所使用的構造函數,readonly 字段可能具有不同的值。另外,const 字段為編譯時常數,而 readonly 字段可用於運行時常數。
using System;
public class ReadOnlyTest
{
class SampleClass
{
public int x;
// Initialize a readonly field
public readonly int y = 25;
public readonly int z;
public SampleClass()
{
// Initialize a readonly instance field
z = 24;
}
public SampleClass(int p1, int p2, int p3)
{
x = p1;
y = p2;
z = p3;
}
}
static void Main()
{
SampleClass p1 = new SampleClass(11, 21, 32); // OK
Console.WriteLine("p1: x={0}, y={1}, z={2}", p1.x, p1.y, p1.z);
SampleClass p2 = new SampleClass();
p2.x = 55; // OK
Console.WriteLine("p2: x={0}, y={1}, z={2}", p2.x, p2.y, p2.z);
}
}
輸出
p1: x=11, y=21, z=32
p2: x=55, y=25, z=24
7.~~~~sealed:由sealed修飾的類是不能夠被繼承的。不允許用abstract修飾密封類。
密封類:由sealed關鍵字修飾的類。
例子:
Public sealed class MyClass
{
Public Int a;
}
MyClass是不能被繼承的。
8.~~~~static:用於聲明屬於類型本身而不是屬於特定對象的靜態成員。
? 注意!!!!!:常數或者類型聲明隱式地是靜態成員。
? 不能通過實例引用靜態成員。然而,可以通過類型名稱引用它
9.~~~~~unsafe:表示不安全的上下文。任何涉及指針的操作都要求有不安全的上下文。Unsafe用作可調用成員的生命修飾符。
例子:不安全范圍從參數列表一直到函數結尾,所以可以在參數列表中使用指針。
Static unsafe void FastCopy(byte* bt, int count)
{ //函數體,其中可以使用指針! }
若要編譯非托管代碼,必須指定unsafe編譯器選項.
10.~~~~virtual:用於修飾可以在子類中重寫的方法或屬性.此種方法或屬性稱為 虛擬成員.虛擬成員可以在派生類中用override重寫.
注意!!!!!:
不能重寫非虛方法,不能將其與static, abstract,和override起使用.
不能在靜態屬性或方法上使用virtual.
在運行時,為虛方法檢查對象中是否有重寫的方法,如果有,則調用重寫的方法,否則調用基類的方法.
10.~~~~volatile:
volatile 關鍵字表示字段可能被多個並發執行線程修改。聲明為 volatile 的字段不受編譯器優化(假定由單個線程訪問)的限制。這樣可以確保該字段在任何時間呈現的都是最新的值。
volatile 修飾符通常用於由多個線程訪問而不使用 lock 語句語句對訪問進行序列化的字段。volatile 關鍵字可應用於以下類型:
? 引用類型。
? 指針類型(在不安全的上下文中)。
? 整型,如 sbyte、byte、short、ushort、int、uint、char、float 和 bool。
? 具有整數基類型的枚舉類型。
? 已知為引用類型的泛型類型參數。
? IntPtr 和 UIntPtr。
所涉及的類型必須是類或結構的字段。不能將局部變量聲明為 volatile
例子:
class MainClass
{
public volatile int i;//定義在main函數之外,是全局變量.
Test(int _i)
{
i = _i;
}
static void Main()
{
// ...
}
}
6.命名空間關鍵字
一.namespace
1.Namespace :用於聲明一個空間。其中可以包含:另一個命名空間,class,interface,struct,enum,delegate.
2.每一個文件中都有默認的全局命名空間,命名空間的默認訪問權限是公共的,且不可以改變。
3.可以在多個聲明中定義一個命名空間。
namespace MyCompany.Proj1
{
class MyClass
{
}
}
namespace MyCompany.Proj1
{
class MyClass1
{
}
}
二.Using
Using關鍵字的主要用途:1.using 指令:用於為命名空間創建別名或導入其他命名空間中定義的類型。
2.using 語句:定義一個范圍,在范圍的末尾將處理對象。
1.using指令:1.創建命名空間的別名。以便易於將標示符限定到命名空間或類。
2.允許在命名空間中使用(其他命名空間中的)類型。
using 別名 = 希望被起別名的命名空間或類;
例子:
using System; //using 指令
using AliasToMyClass = NameSpace1.MyClass; // 為類起別名
namespace NameSpace1
{
public class MyClass
{
public override string ToString()
{
return "You are in NameSpace1.MyClass";
}
}
}
namespace NameSpace2
{
class MyClass
{
}
}
namespace NameSpace3
{
// Using directive:
using NameSpace1;//using指令,可以使用其中定義的類型而不
//名命名空間
// Using directive:
using NameSpace2;
class MainClass
{
static void Main()
{
AliasToMyClass somevar = new AliasToMyClass();
Console.WriteLine(somevar);
}
}
}
2.using 語句
1.定義一個范圍,在范圍的末尾處理對象。
注意!!!!!:在using語句中創建一個實例,可確保在using語句結束時,釋放該對象。但是,被實例化的對象(他所屬的類)中必須實現
System.IDisposable接口中的disposable方法,就是利用該方法釋放對象。
例子:
using System;
using System.Collections.Generic;
using System.Text;
namespace 真的是關鍵字
{
class C : IDisposable //繼承IDisposable接口
{
public void UseLimitedResource()
{
Console.WriteLine("Using limited resource...");
}
void IDisposable.Dispose()//實現Dispose()方法
{
Console.WriteLine("Disposing limited resource.");
}
}
class Program
{
static void Main()
{
using (C c = new C())
{
c.UseLimitedResource();
}
Console.WriteLine("Now outside using statement.");
Console.ReadLine();
}
}
}
輸出:
Using limited resource...
Disposing limited resource.
Now outside using statement.
語法:using (C c = new C())
{
c.UseLimitedResource();
}
在CLR決定讓GC回收某些有限資源之前釋放它們,有時很有用,尤其對於象文件句柄,網絡連接的有限資源。
7.運算符關鍵字
一.as
作用:用於執行可兼容類型之間的轉換。
語法格式:expression as type
例子:string s = objArray[i] as string;
1.As運算符類似於類型轉換,不同的是,當轉換失敗時,類型轉換將引發異常,而,as運算符將返回空即NULL。
2.其中的expression表達式只被計算一次。
例子:
using System;
class Class1
{
}
class Class2
{
}
class MainClass
{
static void Main()
{
object[] objArray = new object[6];
objArray[0] = new Class1();
objArray[1] = new Class2();
objArray[2] = "hello";
objArray[3] = 123;
objArray[4] = 123.4;
objArray[5] = null;
for (int i = 0; i < objArray.Length; ++i)
{
string s = objArray[i] as string;
Console.Write("{0}:", i);
if (s != null)
{
Console.WriteLine("'" + s + "'");
}
else
{
Console.WriteLine("not a string");
}
}
}
}
輸出:
0:not a string
1:not a string
2:'hello'
3:not a string
4:not a string
5:not a string
二.Is關鍵字
1.Is:用於檢查對象在運行時的類型是否與給定類型兼容。
2.語法格式:expression is type
例子:
3.當expression為非空並且可以被轉化為type類型時,整個表達式返回true,否則返回false。
4.is運算符不能被重載。
例子:
using System;
class Class1
{
}
class Class2
{
}
class IsTest
{
static void Test(object o)
{
Class1 a;
Class2 b;
if (o is Class1)
{
Console.WriteLine("o is Class1");
a = (Class1)o;
// Do something with "a."
}
else if (o is Class2)
{
Console.WriteLine("o is Class2");
b = (Class2)o;
// Do something with "b."
}
else
{
Console.WriteLine("o is neither Class1 nor Class2.");
}
}
static void Main()
{
Class1 c1 = new Class1();
Class2 c2 = new Class2();
Test(c1);
Test(c2);
Test("a string");
}
}
輸出:
o is Class1
o is Class2
o is neither Class1 nor Class2.
3.new關鍵字
New關鍵字在C#中可以用作:1.運算符
2.修飾符
New運算符:用於在堆上創建對象和調用構造函數。
New修飾符:用於隱藏基類成員的繼承成員。
一. New運算符:用於在堆上創建對象和調用構造函數。
二. 堆是在運行是根據需要分配的,而棧在編譯時分配的。
例子:
Class1 o = new Class1();
int i = new int();為值類型調用默認構造函數,i=0;
注意!!!!!:為結構聲明默認構造函數是錯誤的。但是可以聲明參數化構造函數。
值類型對象是在棧(stack)上創建的,而引用類型是在堆(heap)上創建的。
不能重載new關鍵字
對值類型如果不進行人為初始化,編譯器會對他進行默認初始化。對引用類型不進行初始化則為空(NULL)。
例子:
using System;
using System.Collections.Generic;
using System.Text;
namespace 真的是關鍵字
{
struct SampleStruct
{
public int x;
public int y;
public SampleStruct(int x, int y)
{
this.x = x;
this.y = y;
}
}
class SampleClass
{
public string name;
public int id;
public SampleClass()
{
}
public SampleClass(int id, string name)
{
this.id = id;
this.name = name;
}
}
class MainClass
{
static void Main()
{
//結構類型默認初始化
SampleStruct Location1 = new SampleStruct();
SampleClass Employee1 = new SampleClass();
// Display values:
Console.WriteLine("Default values:");
Console.WriteLine(" Struct members: {0}, {1}",
Location1.x, Location1.y);
Console.WriteLine(" Class members: {0}, {1}",
Employee1.name, Employee1.id);
// Create objects using parameterized constructors:
SampleStruct Location2 = new SampleStruct(10, 20);
SampleClass Employee2 = new SampleClass(1234, "John Martin Smith");
// Display values:
Console.WriteLine("Assigned values:");
Console.WriteLine(" Struct members: {0}, {1}",
Location2.x, Location2.y);
Console.WriteLine(" Class members: {0}, {1}",
Employee2.name, Employee2.id);
Console.ReadLine();
}
}
}
三. New修飾符:用於以顯式的形式隱藏從基類繼承來的成員。即:告訴編譯器或CLR我要有意隱藏基類的同簽名的成員。隱藏繼承的成員意味着該成員的派生版本將替換基類版本
四.通過繼承方式實現名稱隱藏:引入與基類中要隱藏的成員具有相同簽名的派生類成員。
注意!!!!!在同一成員上同時使用new和override是錯誤的。
例子:
using System;
using System.Collections.Generic;
using System.Text;
namespace 真的是關鍵字
{
public class BaseC
{
public static int x = 55;
public static int y = 22;
}
public class DerivedC : BaseC
{
// Hide field 'x'
new public static int x = 100;
static void Main()
{
// Display the new value of x:
Console.WriteLine(x);
// Display the hidden value of x:
Console.WriteLine(BaseC.x);
// Display the unhidden member y:
Console.WriteLine(y);
Console.ReadLine();
}
}
}
4,sizeof關鍵字
1. sizeof關鍵字:用於獲得值類型的大小,以字節為單位。
2. 語法格式:sizeof(type)
3. 注意!!!!!sizeof() 只能用於值類型,不能用於引用類型,並且只能用於unsafe模式下。Sizeof()不能被重載。
例子:
using System;
using System.Collections.Generic;
using System.Text;
namespace 真的是關鍵字
{
class MainClass
{
unsafe static void Main()
{
Console.WriteLine("The size of short is {0}.", sizeof(short));
Console.WriteLine("The size of int is {0}.", sizeof(int));
Console.WriteLine("The size of long is {0}.", sizeof(long));
}
}
}
五.Typeof關鍵字
1.typeof()關鍵字:用於獲得某一類型的System.Type對象。
2.語法格式:typeof( type )
例子:
System.Type type = typeof(int);
4. typeof()運算符不能重載。要獲得一個對象運行時的類型,可以使用.NET框架中的方法GetType().
5. 例子:
int i = 0;
System.Type type = i.GetType();
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace 真的是關鍵字
{
public class SampleClass
{
public int sampleMember;
public void SampleMethod()
{
}
static void Main()
{
Type t = typeof(SampleClass);
// Alternatively, you could use
// SampleClass obj = new SampleClass();
// Type t = obj.GetType();
Console.WriteLine("Methods:");
MethodInfo[] methodInfo = t.GetMethods();
foreach (MethodInfo mInfo in methodInfo)
{
Console.WriteLine(mInfo.ToString());
}
Console.WriteLine("Members:");
MemberInfo[] memberInfo = t.GetMembers();
foreach (MemberInfo mInfo in memberInfo)
{
Console.WriteLine(mInfo.ToString());
}
Console.ReadLine();
}
}
}
六.True關鍵字
1.true運算符:用戶可以自定義true()運算符,該運算符返回bool值true表示真,false表示假。
2.如果定義了true或者false中的一個,那么必須定義另一個。
3.true文字值:表示bool的真。
七.false關鍵字
1.false運算符:用戶可以自定義false()運算符,該運算符返回bool型值true表示假,false表示真。
2.如果定義了true或者false中的一個,那么必須定義另一個。
3.false文字值:表示bool的假。
例子:
sing System;
class TestClass
{
static void Main()
{
Bool b=false;
bool a = true;
Console.WriteLine( a ? "yes" : "no" );
Console.WriteLine( b ? "yes" : "no" );
}
}
八.Stackalloc關鍵字
1.stackalloc:該運算符用於在堆棧上分配內存塊。
2.語法格式:
type * ptr = stackalloc type [ expr ];
在堆棧上(stack)分配內存,其大小足以包含type類型的expr個元素。
3.內存地址保存在ptr指針中,此內存不受立即回收的制約,生存周期僅限定於該內存塊所在方法的生存周期。沒有在方法返回之前釋放內存的途徑
4.因為涉及指針類型,stackalloc需要不安全的上下文。
8.語句關鍵字
類別 關鍵字
選擇語句 If , else, switch, case
迭代語句 Do, for, foreach, in, while
跳轉語句 Break, continue, default, goto, return
異常處理 Throw, try-catch, try-finally
Checked 和unchecked Checked, unchecked
Fixd語句 Fixed
Lock語句 lock
2.switch關鍵字
1.注意:每個語句塊(無論是case還是default),必須要以(1)break結束(2)goto語句。C#不支持從一個case標簽顯示的貫穿到另一個case標簽。只有一個例外,就是當case語句中沒有代碼時。
例子:
using System;
class SwitchTest
{
static void Main()
{
Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large");
Console.Write("Please enter your selection: ");
string s = Console.ReadLine();
int n = int.Parse(s);
int cost = 0;
switch(n)
{
case 1:
cost += 25;
break;
case 2:
cost += 25;
goto case 1;
case 3:
cost += 50;
goto case 1;
default:
Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");
break;
}
if (cost != 0)
{
Console.WriteLine("Please insert {0} cents.", cost);
}
Console.WriteLine("Thank you for your business.");
}
}
3.foreach和in關鍵字
1.foreach語句使程序為數組和對象集合中的每一個元素重復執行一個嵌入語句組。它用於迭代通過集合以獲得信息,但不應用於更改集合內容以避免產生不可預期的副作用。
2.對數組使用foreach
例子:
class ForEachTest
{
static void Main(string[] args)
{
int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };
foreach (int i in fibarray) //寫出數組名即可
{
System.Console.WriteLine(i);
}
}
}
3.對集合使用foreach
注意:要想迭代通過集合,集合必須滿足一定的要求。
(1) 集合類型:
必須是interface,class或struct。
必須包括有返回類型的名為GetEnumerator的實例方法。
(2) Enumerator類型必須包含:
一個名為Current的屬性,它返回此類型屬性訪問器返回當前元素。
一個名為MoveNext()的方法,它遞增項計數器並在集合存在更多項時返回true。
例子:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
public class MyCollection
{
int[] items;
public MyCollection()
{
items = new int[5] { 1, 2, 3, 4, 5 };
}
public MyEnumerator GetEnumerator()
{
return new MyEnumerator(this);
}
/// <summary>
/// 聲明枚舉類
/// </summary>
public class MyEnumerator
{
int nIndex;
MyCollection collection;
public MyEnumerator(MyCollection coll)
{
collection = coll;
nIndex = -1;
}
public bool MoveNext()
{
nIndex++;
return (nIndex < collection.items.GetLength(0));
}
public int Current
{
get { return (collection.items[nIndex]); }
}
}
}
class Program
{
static void Main(string[] args)
{
MyCollection col = new MyCollection();
Console.WriteLine("Values in the collection are:");
//顯示集合項
foreach(int i in col)
{
Console.WriteLine(i);
}
}
}
}
注:集合類(hashtable等)可以直接使用foreach方法。
3.跳轉語句
1.break:可以終止距離它最近的封閉式循環結構或者條件語句的執行。
2.continue:可以使程序執行它所在的封閉迭代語句的下一次迭代。
3.goto語句
1.goto語句使程序代碼直接轉至標記語句。
2.goto語句的通常用法是:(1)使程序跳轉至特定的switch—case標簽
(2)用於跳出多層嵌套循環
例子:
switch (n)
{
case 1:
cost += 25;
break;
case 2:
cost += 25;
goto case 1;
case 3:
cost += 50;
goto case 1;
default:
Console.WriteLine("Invalid selection.");
break;
}
(2)例子:
using System;
public class GotoTest1
{
static void Main()
{
int x = 200, y = 4;
int count = 0;
string[,] array = new string[x, y];
// Initialize the array:
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
array[i, j] = (++count).ToString();
// Read input:
Console.Write("Enter the number to search for: ");
// Input a string:
string myNumber = Console.ReadLine();
// Search:
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
if (array[i, j].Equals(myNumber))
{
goto Found;
}
}
}
Console.WriteLine("The number {0} was not found.", myNumber);
goto Finish;
Found:
Console.WriteLine("The number {0} is found.", myNumber);
Finish:
Console.WriteLine("End of search.");
}
}
4.異常處理語句
1.不要在try語句塊中對在try外部聲明的變量進行初始化,因為不能保證它一定會被執行。
例子:
Int x;
Try
{
x = 1;
}
Catch{}
Console.Write(x);//////////////////錯誤!!!!!!!!!!!!
例子:try-catch語句,注意catch的順序很重要,要逐步擴大exception的范圍。
using System;
class MainClass
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
}
static void Main()
{
try
{
string s = null;
ProcessString(s);
}
// Most specific:
catch (ArgumentNullException e)
{
Console.WriteLine("{0} First exception caught.", e);
}
// Least specific:
catch (Exception e)
{
Console.WriteLine("{0} Second exception caught.", e);
}
}
}
2.finally:用於清除在try塊中申請的資源,並且執行即使在發生異常時也必須執行的代碼。無論什么情況,finally語句都一定會執行!!!!!!!!!
3.try-catch-finally:通常用法是在try塊中拋出異常並申請資源,在catch塊中捕獲異常處理異常,在finally塊中釋放資源。
例子:
uusing System;
public class EHClass
{
static void Main()
{
try
{
Console.WriteLine("Executing the try statement.");
throw new NullReferenceException();
}
catch (NullReferenceException e)
{
Console.WriteLine("{0} Caught exception #1.", e);
}
catch
{
Console.WriteLine("Caught exception #2.");
}
finally
{
Console.WriteLine("Executing finally block.");
}
}
}
5.checked和unchecked關鍵字
1.checked:對整形算術運算符,和類型轉換提供溢出檢查。
2.unchecked:用於取消對算術運算符和類型轉換的溢出檢查。此時,算法溢出會被忽略,並且結果會被截斷。
3.編譯器默認的是checked。
public int UncheckedAdd(int a, int b)
{
return unchecked(a + b);
}
6.fixed語句
1.fixed語句可以防止變量被垃圾回收器重新定位。
2.只能在不安全的向下文中使用fixed。
3.fixed語句可以設置指向托管變量的指針,並且在fixed語句塊執行期間鎖定該變量。當fixed語句結束,被鎖定的變量被取消鎖定,仍然受GC的管理。C#規定,只有在fixed語句中才可以設置指向托管變量的指針。
5.無法修改在fixed語句中初始化的指針。
6.在不安全模式下,可以在stack(線程堆棧)上分配內存,線程堆棧不受GC管理,所以不用,fixed鎖定。
例子:
using System;
class Point
{
public int x, y;
}
class FixedTest
{
// Unsafe method: takes a pointer to an int.
unsafe static void SquarePtrParam (int* p)
{
*p *= *p;
}
unsafe static void Main()
{
Point pt = new Point();
pt.x = 5;
pt.y = 6;
// Pin pt in place:
fixed (int* p = &pt.x) ////fixed語句,不要指向fixed語句之外的那些////變量
{
SquarePtrParam (p);
}
// pt now unpinned
Console.WriteLine ("{0} {1}", pt.x, pt.y);
}
}
7.lock語句
1.lock語句:用於標記臨界區。方法是獲取給定對象的互斥鎖,在執行語句結束時,釋放該鎖。
2.語法格式:
Lock (Expression) statement_block;
其中:expression 是要被鎖定的對象,它必須是引用類型。
通常,如果要保護實例變量(即lock用在類方法里),則expresson為this,
即用lock(this){ statement },如果要保護靜態變量,則expression為typeof(class)。
注意:不要鎖定public對象,否則會出錯。最佳辦法是鎖定private對象。
例子:
using System;
using System.Threading;
class Account
{
private Object thisLock = new Object();
int balance;
Random r = new Random();
public Account(int initial)
{
balance = initial;
}
int Withdraw(int amount)
{
// This condition will never be true unless the lock statement
// is commented out:
if (balance < 0)
{
throw new Exception("Negative Balance");
}
// Comment out the next line to see the effect of leaving out
// the lock keyword:
lock(thisLock)
{
if (balance >= amount)
{
Console.WriteLine("Balance before Withdrawal : " + balance);
Console.WriteLine("Amount to Withdraw : -" + amount);
balance = balance - amount;
Console.WriteLine("Balance after Withdrawal : " + balance);
return amount;
}
else
{
return 0; // transaction rejected
}
}
}
public void DoTransactions()
{
for (int i = 0; i < 100; i++)
{
Withdraw(r.Next(1, 100));
}
}
}
class Test
{
static void Main()
{
Thread[] threads = new Thread[10];
Account acc = new Account(1000);
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(acc.DoTransactions));
threads[i] = t;
}
for (int i = 0; i < 10; i++)
{
threads[i].Start();
}
}
}
九.類型關鍵字
C#中有三種類型:
1. 值類型
2. 引用類型
3. 指針類型
值類型:
1. 結構:A.數值類型:整型,浮點型,decimal型
B.bool
c.用戶自定義的結構
結構類型:是一種值類型,用於封裝一組相關變量,可以包含構造函數,常量,字段,方法,屬性,索引器,運算符,事件,嵌套類型。
結構可以實現接口,但是不能實現繼承,其中的成員也不能聲明為protected。
2.枚舉:using System;
public class EnumTest
{
enum Range :long {Max = 2147483648L, Min = 255L};
static void Main()
{
long x = (long)Range.Max;
long y = (long)Range.Min;
Console.WriteLine("Max = {0}", x);
Console.WriteLine("Min = {0}", y);
}
}
注意:
1.基於值類型的變量直接包含值。將一個值類型變量賦給另一個值類型變量時,將復制包含的值。這與引用類型變量的賦值不同,引用類型變量的賦值只復制對對象的引用,而不復制對象本身。
2.所有的值類型均隱式派生自 System.ValueType。
3.與引用類型不同,從值類型不可能派生出新的類型。但與引用類型相同的是,結構也可以實現接口。
4.與引用類型不同,值類型不可能包含 null 值。然而,可空類型功能允許將 null 賦給值類型。
例如:Nullable <int> a = null;(但是只能判斷a是否等於null,不能將null作為輸出,否則引發異常)或int? a = null;
4.每種值類型均有一個隱式的默認構造函數來初始化該類型的默認值。有關值類型默認值的信息。
1.bool關鍵字
1. bool是System.Boolean的別名。
2. 轉換:不存在bool類型與其他任何類型的相互轉換。
3. If()條件判斷時必須是bool類型的值。例如:int x = 1; if(x){}是錯誤的。必須將該變量於一個值進行顯示比較。
2.byte關鍵字
1.轉換:byte x = 10; 合法
Int a = 10; byte x = a; 不合法,目標量必須占有更大的存儲空間(byte是目標量),除非進行顯示類型轉換。
3.char關鍵字
4.demical關鍵字
1.demical類型具有更高的精度和更小的范圍。適用於財務和貨幣計算。
2.如果希望將實數視為demical類型。則在后面加上m或M。
例如:demical d = 300.01m;
5.double關鍵字
1.默認情況下,等號右邊的實數將會被視為double類型。但是,要想將整數視為double類型,在后面加上d或者D。
例如: double d = 3d;
6.enum
1.enum關鍵字用於聲明枚舉,enum類型是由一組稱為枚舉數列表的命名常量組成的特殊類型。
2.每種枚舉類型均有一組基礎類型,此基礎類型可以是除char類型之外的任何整形。
例子: using System;
public class EnumTest
{
enum Range :long {Max = 2147483648L, Min = 255L};
//基礎類型是long
static void Main()
{
long x = (long)Range.Max;
long y = (long)Range.Min;
Console.WriteLine("Max = {0}", x);
Console.WriteLine("Min = {0}", y);
}
}
3.從枚舉類型到其他類型需要顯示的類型轉換(無論基礎類型是什么!)。.
7.float關鍵字
1.要想使實數變成float類型,后面加上f.例如:float f = 3.5f;
8.Int關鍵字
9.long類型
1.要想使整數變成long類型,在后面加上l或L。例如:long L = 64L;
10.sbyte
帶符號的byte類型。
11.short類型
帶符號的16位整數。
12.struct關鍵字
1.結構類型:是一種值類型,用於封裝一組相關變量,可以包含構造函數,常量,字段,方法,屬性,索引器,運算符,事件,嵌套類型。
結構可以實現接口,但是不能實現繼承,其中的成員也不能聲明為protected。
2. struct是在stack上分配空間。
3. 結構類型對具有語意的小型結構尤為有用。
4. 聲明結構的默認構造函數(就是沒有參數的構造函數)是錯誤的。因為C#中已經提供了默認構造函數。
5. 在結構中初始化實例字段是錯誤的。
13.uint關鍵字
1.無符號32位整數。
2.在整數后面加上u,即可以把整數變成無符號的數,根據其值的大小判斷是uint還是ulong。
14.ulong關鍵字
1.無符號64位整數。
15.ushort關鍵字
1.無符號16位整數。
九.裝箱和取消裝箱
1.裝箱
1.對值類型裝箱會使之變為一個對象,會在heap(垃圾回收堆)上為其分配存儲空間,創建object對象,並將其值復制到對象。
2.原始值類型和裝箱對象使用不同的內存,可以存儲不同的值。
裝箱轉換
在heap上分配存儲空間創建新對象,是在stack上的object引用其值。(boxed)i和(unboxed)i存儲在不同內存中。
class TestBoxing
{
static void Main()
{
int i = 123;
object o = i; // implicit boxing
i = 456; // change the contents of i
System.Console.WriteLine("The value-type value = {0}", i);
System.Console.WriteLine("The object-type value = {0}", o);
}
}
2.取消裝箱
進行裝箱和取消裝箱都會進行大量計算,降低性能。
1.取消裝箱是將object對象裝換成值類型。
2.取消裝箱將執行下列操作:
A.檢查該object對象,確保它是要轉換成的值類型的一個裝箱值。
B.將object對象的值復制到值類型對象中。
3.要想成功取消裝箱,必須保證:(1)該object對象是某個值的引用,null不行。
(2)object對象必須是在對該值類型的值裝箱時創建的。
(3)取消裝箱必須是顯示的。
取消裝箱轉換
例子:
class TestUnboxing
{
static void Main()
{
int i = 123;
object o = i; // implicit boxing
try
{
int j = (short) o; // attempt to unbox
System.Console.WriteLine("Unboxing OK.");
}
catch (System.InvalidCastException e)
{
System.Console.WriteLine("{0} Error: Incorrect
unboxing.", e.Message);
}
}
}
將short改成int就可以獲得Unboxing ok.
3.引用類型
1.引用類型變量又稱為對象,可以存儲對實際數據的引用。
2.常用的引用類型:class,interface,delegate,object,string.
1.class
2.delegate
3.interface
1.接口的作用是定義某種合約,實現接口的類和結構必須遵守這種合約。
2.一個接口可以繼承多個接口,接口本身並不向其中的成員提供實現,而是有繼承該接口的類和結構實現。
3.當類繼承了類和接口時,類寫在前面。
4.object
1.object類基於system.object類。可以將任何類型的值賦予object類變量。
2.所有數據,無論是預定義的還是用戶自定義的都繼承自object類。
3.object類型是同對象進行拆裝箱的類型。
5.string關鍵字
1.string類型是引用類型,但是當使用==或!=進行比較時,比較的是應用的值,而不是引用本身。
2.[]運算符用於訪問string中的個別字符。
例如:char c = “abcdefd”[2]
C的值是c.
3.@符號:@”abcdefgh”
用@符號的好處是換碼序列將不被處理。但是要想用雙引號,使用””abcd””的形式。
例子:string str = @”””stop!””, he shout!”;
6.格式化輸出
十一.屬性(Attribute)
第一部分
一.訪問關鍵字:base,this~~~~base:訪問基類的成員。用於從派生類中訪問基類的成員,1.調用基類上已經被重寫的方法。2.指定創建派生類實例時應調用的基類構造函數。**對基類的訪問只能在 派生類的構造函數 實例的方法 實例的屬性訪問器 中。屬性訪問器:get,set函數。
注意:!!!!!!!!!不能在靜態方法中使用base關鍵字。例:在子類的方法中寫 base.GetInfo();調用基類的方法。基類中的構造函數重載了,Mybase()和Mybase(int i);在子類的構造函數中public MyDerived():base(int i)public MyDerived(int i):base()
~~~~this:引用當前對象。用於引用為其調用方法的當前實例。靜態成員函數沒有this指針。可以用於從 構造函數,實例方法,實例訪問器 中訪問成員。
this的一般用途:1.限定被相似的名子隱藏的成員public void A(int a, int b ){ this.a=a; this.b=b;}
2.將對象作為參數傳遞到函數中public void ShowInstance(){ print(this); console.writeline("lalalalllalalala");}
3.聲明索引器public int this[int param]{ get{ return array[param]; } set{ array[param]=value; }}注意!!!!!!靜態方法,靜態屬性訪問器或字段聲明中不能用this。
二.轉換關鍵字:explicit, implicit, operator1~~~~explicit:用於聲明用戶定義的 顯式類型轉換運算符。例: class MyType{ public static explicit operator MyType(int i) { //從int顯式轉換成MyType類型的代碼!!! }}
顯式類型轉換符必須通過類型轉換調用。需要在轉換失敗時拋出異常。if(轉換失敗的條件)throw new ArgumentException();
int i;MyType x = (MyType)i;注意!!!!!!!如果轉換可能導致信息丟失,則使用explicit關鍵字。
2~~~~implicit:用於聲明用戶定義的 隱式類型轉換運算符。例:class MyType{ public static implicit operator int(MyType i) { //從MyType隱式轉換成Mint類型的代碼!!! }} MyType i;int x = i;注意!!!!!!!!!!!由於隱式轉換在程序員未指定的情況下發生,所以必須防止出現不良的后果。只有在一定不會出現異常和信息丟失時才可以使用implicit,否則使用expicit。
3~~~~operator:用於聲明用戶在類或結構中自定義的運算符。有四種形式:
public static 結果類型 operator unary-operator (參數類型 參數名)public static implict operator 目標類型 (輸入類型 參數名) public static explict operator 目標類型 (輸入類型 參數名)
//implict中,目標類型一般是封閉類型,例如:int, double, byte等。//explict中,目標類型一般是自定義類型,例如:MyType等。
三.文字關鍵字:null,false,true1~~~~null:表示不引用任何對象的空引用的值。null是引用類型的默認值。
2~~~~true: true運算符:用戶自定義的類型可以重載true運算符,用來表示是否滿足條件,若滿足則返回bool值的true,否則返回false。注意!!!!!!!若在自定義類型中定義了true運算符,則必須定義false運算符。 true文字值:表示bool的真。
3~~~~false: false運算符:用戶自定義的類型可以重載false運算符,用來表示是否滿足條件,若不滿足則返回bool值的true,否則返回false。注意!!!!!!!若在自定義類型中定義了false運算符,則必須定義true運算符。 false文字值:表示bool的假。 true和false運算符可以用在任何條件判斷中。
四.方法參數關鍵字:params,ref,out1~~~~params:用於指定在參數數目可變處,采用參數的方法參數。只能有一個params,並且在他后面不能再有參數。~方法參數:如果在為方法聲明參數時未使用 ref 或 out,則該參數可以具有關聯的值。可以在方法中更改該值,但當控制傳遞回調用過程時,不會保留更改的值using System;public class MyClass {
public static void UseParams(params int[] list) { for (int i = 0 ; i < list.Length; i++) { Console.WriteLine(list[i]); } Console.WriteLine(); }
public static void UseParams2(params object[] list) { for (int i = 0 ; i < list.Length; i++) { Console.WriteLine(list[i]); } Console.WriteLine(); }
static void Main() { UseParams(1, 2, 3); UseParams2(1, 'a', "test");
// An array of objects can also be passed, as long as // the array type matches the method being called. int[] myarray = new int[3] {10,11,12}; UseParams(myarray); }}
輸出 123
1atest
101112//把1,2,3三個參數當成一個數組處理,在最后輸出Console.WriteLine();
2~~~~ref:使方法可以引用傳遞到該方法的參數。當程序跳轉到調用方法處的時候,在方法中對參數所做的任何改動都將傳遞給參數。類似於傳地址。注意!!!!!必須將參數作為ref參數 顯示 的傳遞到方法。參數必須顯示的初始化!屬性不是變量不能作為ref參數傳遞。例子:using System;using System.Collections.Generic;using System.Text;namespace 真的是關鍵字{ class Program { public static void TestRef(ref string i) { i = "change once!"; }
public static void TestNoRef(string i) { i = "change twice!"; }
static void Main(string[] args) { string i = "begining!"; Console.WriteLine(i);
TestRef(ref i); Console.WriteLine(i);
TestNoRef(i); Console.WriteLine(i);
Console.ReadLine(); } }}輸出:beginning! Change once! Change once!
3.~~~~out:使方法可以引用傳遞到該方法的同一個變量。當程序跳轉到方法調用處時,在方法中對變量所做的任何改動都將傳遞給該變量。注意!!!!!當希望方法返回多個值時,聲明out非常有用。 一個方法可以有多個out參數。 必須將參數作為out參數顯示的傳遞到方法。 不必初始化作為out參數的變量。 屬性不是變量不能作為out變量。注意!!!!!ref參數必須顯示初始化,而out參數不用。例子:using System;using System.Collections.Generic;using System.Text;
namespace 真的是關鍵字{ class Program { public static int TestOut(out string i) { i = "change once!"; return -1; }
static void Main(string[] args) { string i = "begining!"; Console.WriteLine(i);
Console.WriteLine(TestOut(out i)); Console.WriteLine(i);
Console.ReadLine(); } }}5.修飾關鍵字修飾符作用訪問修飾符PublicPrivateInternalprotected指定聲明的類型和成員的可訪問性abstract指示某個類只能是其他類的基類,虛基類。Const指定無法修改字段或局部變量的值,只能在聲明時初始化。Event聲明一個事件Extern指示外部實現此方法Override提供從基類繼承的 虛擬成員 的新實現Readonly聲明的字段只能在聲明時或構造函數中初始化。
Sealed指定該類不能被繼承Static聲明對象屬於類本身不屬於特定的對象。Unsafe聲明不安全的上下文Virtual在派生類中實現具體方法,可以重寫。Volatile指示字段可以由操作系統,硬件或並發的線程等在程序中修改。
1.訪問關鍵字聲明的可訪問性意義public訪問不受限制Protected訪問僅限於包含類或從包含類派生的類Internal訪問僅限於當前項目Protected internal訪問僅限於包含類或從包含類派生的當前項目和類Private訪問僅限於包含類
不嵌套在其他類型中的頂級類型只能有public和internal可訪問性,默認是internal。類型默認的成員可訪問性允許的訪問性枚舉Public無(internal)PublicProtected類PrivateInternalPrivateProtected internal接口Public無(internal)Public結構PrivateInternalPrivate
嵌套類型的可訪問性取決於它的可訪問域,而且不能超出包含它類型的可訪問域。
2.可訪問域1.~~~~可訪問域:用於指定程序段中可以引用該成員的位置。如果是嵌套類型,那么它的可訪問域由成員的訪問級別和直接包含該成員的類型的可訪問域共同決定。using System;using System.Collections.Generic;using System.Text;
namespace 真的是關鍵字{ public class T1 { public static int publicInt; internal static int internalInt; private static int privateInt = 0; // CS0414
public class M1 { public static int publicInt; internal static int internalInt; private static int privateInt = 0; // CS0414 }
private class M2 { public static int publicInt = 0; internal static int internalInt = 0; private static int privateInt = 0; // CS0414 } }
class MainClass { static void Main() { // Access is unlimited: T1.publicInt = 1; // Accessible only in current assembly: T1.internalInt = 2; // Error: inaccessible outside T1: // T1.myPrivateInt = 3;
// Access is unlimited: T1.M1.publicInt = 1; // Accessible only in current assembly: T1.M1.internalInt = 2; // Error: inaccessible outside M1: // T1.M1.myPrivateInt = 3;
// Error: inaccessible outside T1: // T1.M2.myPublicInt = 1; // Error: inaccessible outside T1: // T1.M2.myInternalInt = 2; // Error: inaccessible outside M2: // T1.M2.myPrivateInt = 3; } }}3.對使用可訪問性級別的限制1~~~~基類的可訪問性必須不小於派生類。2~~~~派生類的可訪問性必須不大於基類。3~~~~成員的可訪問性至少是包含它的類。例子:Class BaseClass{};Public class MyClass: BaseClass{};這是錯誤的!!!!!!!!!!!!!!!!
對使用聲明的而訪問型級別限制上下文備注類類類型的直接基類必須至少與類類型本身具有同樣的可訪問性。接口接口類型的顯式基類接口必須至少與接口類型具有同樣的可訪問性。委托返回類型和參數類型必須至少與委托本身具有同樣的可訪問性。方法返回類型和參數類型必須至少與方法本身具有同樣的可訪問性。運算符返回類型和參數類型必須至少與運算符本身具有同樣的可訪問性。構造函數它的參數必須至少與構造函數本身具有同樣的可訪問性。字段(它是包含在類或結構中的對象或值)字段的可訪問性必須至少與字段本身具有同樣的可訪問性。4.訪問修飾關鍵字1~~~~internal:是類型和類型成員的訪問修飾符,只有在同一個程序集中才可以訪問。通俗的說就是:如果用internal修飾,那么只能在定義它的.cs文件中訪問它。在別的文件中訪問就會出錯。
5.其它修飾關鍵字1~~~~abstract:可用來修飾 類,方法和屬性。(1)在類的聲明中使用abstract,表示這個類只能作為其他類的基類,即抽象類。 抽象類的特點:a.抽象類不能實例化。 b.抽象類可以包含抽象方法和抽象訪問器。 c.不能用sealed修飾抽象類,否則,該類不能被繼承。 d.從抽象類派生的非抽象類必須包含繼承來的所有抽象方法和抽象訪問器的實實現。(2) 在方法和屬性中使用abstract,表示此方法或屬性 不包含實現。即抽象方法和抽象屬性。抽象方法的特點:A.抽象方法是隱式的virtual方法。B.只允許在抽象類中定義抽象方法。C.抽象方法不提供實現,所以沒有方法體。 格式如下:沒有{}!!!! Public abstract void MyMethod();D.實現由重寫方法提供,他是非抽象的。E.抽象方法中使用virtual, static, override關鍵字是錯誤的。F.靜態屬性上不能使用abstract關鍵字。G.在派生類中,通過使用override 可以重寫抽象的繼承屬性。H.抽象類必須為所有接口成員提供實現,或將其映射到抽象方法上去。 // abstract_keyword.cs// Abstract Classesusing System;abstract class BaseClass // Abstract class{ protected int _x = 100; protected int _y = 150; public abstract void AbstractMethod(); //Abstract methodpublic abstract int X { get; } //abstract property public abstract int Y { get; }}
class DerivedClass : BaseClass{ public override void AbstractMethod() { _x++; _y++; }
} public override int X // overriding property { get { return _x + 10; }
public override int Y // overriding property { get { return _y + 10; } }
static void Main() { DerivedClass o = new DerivedClass(); o.AbstractMethod(); Console.WriteLine("x = {0}, y = {1}", o.X, o.Y); }}輸出 x = 111, y = 161 2.~~~~const:用來指定字段或局部變量的之不能被修改。Public const int a=1,b=2;
3.~~~~event:用於指定一個事件。指定當代碼中的某些事件發生時調用的委托。此委托可以有一個或多個相關聯的方法。創建事件的步驟:1.創建或標示一個委托。先有委托后定義事件。2.創建一個類,其中包含:A.委托創建的事件。B.調用此事件的方法。3.定義將方法連接到事件的類。4.使用事件:創建包含事件聲明類的對象。4~~~~extern:表示方法在外部實現。注意!!!!!不能將extern和abstract一起使用。格式舉例:public static extern int MyMethod (int x); 沒有{} 5~~~~override:用於修改方法和屬性,通過 override 聲明重寫的方法稱為重寫基方法。重寫的基方法必須與 override 方法具有相同的簽名。重寫基方法:有重寫聲明的方法。注意!!!!!不能重寫非虛方法或靜態方法。 不能使用以下關鍵字修飾重寫方法:new,static,virtual,abstract 重寫的屬性與重寫的方法的要求是一樣的。 重寫的方法中可以調用基類的原來的virtual方法。namespace 真的是關鍵字{ public class Square { public double x; public Square(double x) { this.x = x; } public virtual double Area() { return (x*x); } }
class Cube : Square { public Cube(double x):base(x) { }
public override double Area() { return (6*base.Area());//調用base即基類的方法。 } }
class MainClass { static void Main() { double x = 5.2; Square s = new Square(x); Square c = new Cube(x); Console.WriteLine("Area of Square is{0:F2}",s.Area()); Console.WriteLine("Area of Cube is {0:F2}", c.Area()); Console.ReadLine(); } }}
6.~~~~readonly:只可以使用在字段上,被readonly修飾的字段的賦值只能作為 聲明的一部分或者在構造函數中。 1.在聲明中初始化:public readonly double a=1.1; 2.在構造函數中。readonly 關鍵字與 const 關鍵字不同:const 字段只能在該字段的聲明中初始化。readonly段可以在聲明或構造函數中初始化。因此,根據所使用的構造函數,readonly 字段可能具有不同的值。另外,const 字段為編譯時常數,而 readonly 字段可用於運行時常數。using System;public class ReadOnlyTest{ class SampleClass { public int x; // Initialize a readonly field public readonly int y = 25; public readonly int z;
public SampleClass() { // Initialize a readonly instance field z = 24; }
public SampleClass(int p1, int p2, int p3) { x = p1; y = p2; z = p3; } }
static void Main() { SampleClass p1 = new SampleClass(11, 21, 32); // OK Console.WriteLine("p1: x={0}, y={1}, z={2}", p1.x, p1.y, p1.z); SampleClass p2 = new SampleClass(); p2.x = 55; // OK Console.WriteLine("p2: x={0}, y={1}, z={2}", p2.x, p2.y, p2.z); }} 輸出p1: x=11, y=21, z=32p2: x=55, y=25, z=247.~~~~sealed:由sealed修飾的類是不能夠被繼承的。不允許用abstract修飾密封類。密封類:由sealed關鍵字修飾的類。 例子:Public sealed class MyClass{ Public Int a;}MyClass是不能被繼承的。
8.~~~~static:用於聲明屬於類型本身而不是屬於特定對象的靜態成員。?注意!!!!!:常數或者類型聲明隱式地是靜態成員。? 不能通過實例引用靜態成員。然而,可以通過類型名稱引用它9.~~~~~unsafe:表示不安全的上下文。任何涉及指針的操作都要求有不安全的上下文。Unsafe用作可調用成員的生命修飾符。例子:不安全范圍從參數列表一直到函數結尾,所以可以在參數列表中使用指針。Static unsafe void FastCopy(byte* bt, int count){ //函數體,其中可以使用指針! }若要編譯非托管代碼,必須指定unsafe編譯器選項.
10.~~~~virtual:用於修飾可以在子類中重寫的方法或屬性.此種方法或屬性稱為 虛擬成員.虛擬成員可以在派生類中用override重寫.注意!!!!!:不能重寫非虛方法,不能將其與static, abstract,和override起使用.不能在靜態屬性或方法上使用virtual.在運行時,為虛方法檢查對象中是否有重寫的方法,如果有,則調用重寫的方法,否則調用基類的方法.10.~~~~volatile:volatile 關鍵字表示字段可能被多個並發執行線程修改。聲明為 volatile 的字段不受編譯器優化(假定由單個線程訪問)的限制。這樣可以確保該字段在任何時間呈現的都是最新的值。volatile 修飾符通常用於由多個線程訪問而不使用 lock 語句語句對訪問進行序列化的字段。volatile 關鍵字可應用於以下類型:?引用類型。?指針類型(在不安全的上下文中)。?整型,如 sbyte、byte、short、ushort、int、uint、char、float 和 bool。?具有整數基類型的枚舉類型。?已知為引用類型的泛型類型參數。?IntPtr 和 UIntPtr。所涉及的類型必須是類或結構的字段。不能將局部變量聲明為 volatile例子:class MainClass{ public volatile int i;//定義在main函數之外,是全局變量.
Test(int _i) { i = _i; } static void Main() { // ... }}6.命名空間關鍵字一.namespace1.Namespace :用於聲明一個空間。其中可以包含:另一個命名空間,class,interface,struct,enum,delegate.2.每一個文件中都有默認的全局命名空間,命名空間的默認訪問權限是公共的,且不可以改變。3.可以在多個聲明中定義一個命名空間。namespace MyCompany.Proj1 { class MyClass { }}
namespace MyCompany.Proj1 { class MyClass1 { }}二.UsingUsing關鍵字的主要用途:1.using 指令:用於為命名空間創建別名或導入其他命名空間中定義的類型。 2.using 語句:定義一個范圍,在范圍的末尾將處理對象。1.using指令:1.創建命名空間的別名。以便易於將標示符限定到命名空間或類。 2.允許在命名空間中使用(其他命名空間中的)類型。using 別名 = 希望被起別名的命名空間或類;例子:using System; //using 指令 using AliasToMyClass = NameSpace1.MyClass; // 為類起別名
namespace NameSpace1 { public class MyClass { public override string ToString() { return "You are in NameSpace1.MyClass"; } }}
namespace NameSpace2 { class MyClass { }}
namespace NameSpace3 { // Using directive: using NameSpace1;//using指令,可以使用其中定義的類型而不//名命名空間 // Using directive: using NameSpace2;
class MainClass { static void Main() { AliasToMyClass somevar = new AliasToMyClass(); Console.WriteLine(somevar); } }}2.using 語句1.定義一個范圍,在范圍的末尾處理對象。注意!!!!!:在using語句中創建一個實例,可確保在using語句結束時,釋放該對象。但是,被實例化的對象(他所屬的類)中必須實現System.IDisposable接口中的disposable方法,就是利用該方法釋放對象。例子:using System;using System.Collections.Generic;using System.Text;
namespace 真的是關鍵字{ class C : IDisposable //繼承IDisposable接口 { public void UseLimitedResource() { Console.WriteLine("Using limited resource..."); }
void IDisposable.Dispose()//實現Dispose()方法 { Console.WriteLine("Disposing limited resource."); } }
class Program { static void Main() { using (C c = new C()) { c.UseLimitedResource(); } Console.WriteLine("Now outside using statement."); Console.ReadLine(); } }}輸出:Using limited resource...Disposing limited resource.Now outside using statement.語法:using (C c = new C()) { c.UseLimitedResource(); }在CLR決定讓GC回收某些有限資源之前釋放它們,有時很有用,尤其對於象文件句柄,網絡連接的有限資源。
7.運算符關鍵字一.as作用:用於執行可兼容類型之間的轉換。語法格式:expression as type例子:string s = objArray[i] as string;1.As運算符類似於類型轉換,不同的是,當轉換失敗時,類型轉換將引發異常,而,as運算符將返回空即NULL。2.其中的expression表達式只被計算一次。例子:
using System;class Class1{}
class Class2{}
class MainClass{ static void Main() { object[] objArray = new object[6]; objArray[0] = new Class1(); objArray[1] = new Class2(); objArray[2] = "hello"; objArray[3] = 123; objArray[4] = 123.4; objArray[5] = null;
for (int i = 0; i < objArray.Length; ++i) { string s = objArray[i] as string; Console.Write("{0}:", i); if (s != null) { Console.WriteLine("'" + s + "'"); } else { Console.WriteLine("not a string"); } } }}輸出:0:not a string1:not a string2:'hello'3:not a string4:not a string5:not a string
二.Is關鍵字1.Is:用於檢查對象在運行時的類型是否與給定類型兼容。2.語法格式:expression is type例子:3.當expression為非空並且可以被轉化為type類型時,整個表達式返回true,否則返回false。4.is運算符不能被重載。例子:using System;class Class1{}class Class2{}
class IsTest{ static void Test(object o) { Class1 a; Class2 b;
if (o is Class1) { Console.WriteLine("o is Class1"); a = (Class1)o; // Do something with "a." } else if (o is Class2) { Console.WriteLine("o is Class2"); b = (Class2)o; // Do something with "b." } else { Console.WriteLine("o is neither Class1 nor Class2."); } } static void Main() { Class1 c1 = new Class1(); Class2 c2 = new Class2(); Test(c1); Test(c2); Test("a string"); }}輸出:o is Class1o is Class2o is neither Class1 nor Class2.3.new關鍵字New關鍵字在C#中可以用作:1.運算符 2.修飾符New運算符:用於在堆上創建對象和調用構造函數。New修飾符:用於隱藏基類成員的繼承成員。
一.New運算符:用於在堆上創建對象和調用構造函數。二.堆是在運行是根據需要分配的,而棧在編譯時分配的。例子:Class1 o = new Class1();int i = new int();為值類型調用默認構造函數,i=0;注意!!!!!:為結構聲明默認構造函數是錯誤的。但是可以聲明參數化構造函數。值類型對象是在棧(stack)上創建的,而引用類型是在堆(heap)上創建的。不能重載new關鍵字對值類型如果不進行人為初始化,編譯器會對他進行默認初始化。對引用類型不進行初始化則為空(NULL)。例子:using System;using System.Collections.Generic;using System.Text;
namespace 真的是關鍵字{ struct SampleStruct { public int x; public int y; public SampleStruct(int x, int y) { this.x = x; this.y = y; } }
class SampleClass { public string name; public int id;
public SampleClass() { }
public SampleClass(int id, string name) { this.id = id; this.name = name; } }
class MainClass { static void Main() { //結構類型默認初始化 SampleStruct Location1 = new SampleStruct(); SampleClass Employee1 = new SampleClass();
// Display values: Console.WriteLine("Default values:"); Console.WriteLine(" Struct members: {0}, {1}", Location1.x, Location1.y); Console.WriteLine(" Class members: {0}, {1}", Employee1.name, Employee1.id);
// Create objects using parameterized constructors: SampleStruct Location2 = new SampleStruct(10, 20); SampleClass Employee2 = new SampleClass(1234, "John Martin Smith");
// Display values: Console.WriteLine("Assigned values:"); Console.WriteLine(" Struct members: {0}, {1}", Location2.x, Location2.y); Console.WriteLine(" Class members: {0}, {1}", Employee2.name, Employee2.id);
Console.ReadLine(); } }}三.New修飾符:用於以顯式的形式隱藏從基類繼承來的成員。即:告訴編譯器或CLR我要有意隱藏基類的同簽名的成員。隱藏繼承的成員意味着該成員的派生版本將替換基類版本四.通過繼承方式實現名稱隱藏:引入與基類中要隱藏的成員具有相同簽名的派生類成員。注意!!!!!在同一成員上同時使用new和override是錯誤的。例子:using System;using System.Collections.Generic;using System.Text;
namespace 真的是關鍵字{ public class BaseC { public static int x = 55; public static int y = 22; }
public class DerivedC : BaseC { // Hide field 'x' new public static int x = 100;
static void Main() { // Display the new value of x: Console.WriteLine(x); // Display the hidden value of x: Console.WriteLine(BaseC.x); // Display the unhidden member y: Console.WriteLine(y);
Console.ReadLine(); } }}
4,sizeof關鍵字1.sizeof關鍵字:用於獲得值類型的大小,以字節為單位。2.語法格式:sizeof(type)3.注意!!!!!sizeof() 只能用於值類型,不能用於引用類型,並且只能用於unsafe模式下。Sizeof()不能被重載。例子:using System;using System.Collections.Generic;using System.Text;
namespace 真的是關鍵字{ class MainClass { unsafe static void Main() { Console.WriteLine("The size of short is {0}.", sizeof(short)); Console.WriteLine("The size of int is {0}.", sizeof(int)); Console.WriteLine("The size of long is {0}.", sizeof(long)); } }} 五.Typeof關鍵字1.typeof()關鍵字:用於獲得某一類型的System.Type對象。2.語法格式:typeof( type )例子:System.Type type = typeof(int);4.typeof()運算符不能重載。要獲得一個對象運行時的類型,可以使用.NET框架中的方法GetType().5.例子:int i = 0;System.Type type = i.GetType();
using System;using System.Collections.Generic;using System.Text;using System.Reflection;
namespace 真的是關鍵字{ public class SampleClass { public int sampleMember; public void SampleMethod() { }
static void Main() { Type t = typeof(SampleClass); // Alternatively, you could use // SampleClass obj = new SampleClass(); // Type t = obj.GetType();
Console.WriteLine("Methods:"); MethodInfo[] methodInfo = t.GetMethods(); foreach (MethodInfo mInfo in methodInfo) { Console.WriteLine(mInfo.ToString()); }
Console.WriteLine("Members:"); MemberInfo[] memberInfo = t.GetMembers(); foreach (MemberInfo mInfo in memberInfo) { Console.WriteLine(mInfo.ToString()); } Console.ReadLine(); } }}六.True關鍵字1.true運算符:用戶可以自定義true()運算符,該運算符返回bool值true表示真,false表示假。2.如果定義了true或者false中的一個,那么必須定義另一個。
3.true文字值:表示bool的真。七.false關鍵字1.false運算符:用戶可以自定義false()運算符,該運算符返回bool型值true表示假,false表示真。2.如果定義了true或者false中的一個,那么必須定義另一個。3.false文字值:表示bool的假。例子:sing System;class TestClass{ static void Main() { Bool b=false; bool a = true; Console.WriteLine( a ? "yes" : "no" );Console.WriteLine( b ? "yes" : "no" ); }}
八.Stackalloc關鍵字1.stackalloc:該運算符用於在堆棧上分配內存塊。2.語法格式:type * ptr = stackalloc type [ expr ];在堆棧上(stack)分配內存,其大小足以包含type類型的expr個元素。3.內存地址保存在ptr指針中,此內存不受立即回收的制約,生存周期僅限定於該內存塊所在方法的生存周期。沒有在方法返回之前釋放內存的途徑4.因為涉及指針類型,stackalloc需要不安全的上下文。
8.語句關鍵字類別關鍵字選擇語句If , else, switch, case迭代語句Do, for, foreach, in, while 跳轉語句Break, continue, default, goto, return異常處理Throw, try-catch, try-finallyChecked 和uncheckedChecked, uncheckedFixd語句FixedLock語句lock2.switch關鍵字1.注意:每個語句塊(無論是case還是default),必須要以(1)break結束(2)goto語句。C#不支持從一個case標簽顯示的貫穿到另一個case標簽。只有一個例外,就是當case語句中沒有代碼時。例子:using System;class SwitchTest { static void Main() { Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large"); Console.Write("Please enter your selection: "); string s = Console.ReadLine(); int n = int.Parse(s); int cost = 0; switch(n) { case 1: cost += 25; break; case 2: cost += 25; goto case 1; case 3: cost += 50; goto case 1; default: Console.WriteLine("Invalid selection. Please select 1, 2, or 3."); break; } if (cost != 0) { Console.WriteLine("Please insert {0} cents.", cost); } Console.WriteLine("Thank you for your business."); }}3.foreach和in關鍵字1.foreach語句使程序為數組和對象集合中的每一個元素重復執行一個嵌入語句組。它用於迭代通過集合以獲得信息,但不應用於更改集合內容以避免產生不可預期的副作用。2.對數組使用foreach例子:class ForEachTest{ static void Main(string[] args) { int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 }; foreach (int i in fibarray) //寫出數組名即可 { System.Console.WriteLine(i); } }}3.對集合使用foreach注意:要想迭代通過集合,集合必須滿足一定的要求。(1)集合類型: 必須是interface,class或struct。 必須包括有返回類型的名為GetEnumerator的實例方法。(2)Enumerator類型必須包含: 一個名為Current的屬性,它返回此類型屬性訪問器返回當前元素。 一個名為MoveNext()的方法,它遞增項計數器並在集合存在更多項時返回true。例子:using System;using System.Collections.Generic;using System.Text;
namespace ConsoleApplication1{ public class MyCollection { int[] items; public MyCollection() { items = new int[5] { 1, 2, 3, 4, 5 }; } public MyEnumerator GetEnumerator() { return new MyEnumerator(this); }
/// <summary> /// 聲明枚舉類 /// </summary> public class MyEnumerator { int nIndex; MyCollection collection; public MyEnumerator(MyCollection coll) { collection = coll; nIndex = -1; }
public bool MoveNext() { nIndex++; return (nIndex < collection.items.GetLength(0)); }
public int Current { get { return (collection.items[nIndex]); } } } } class Program { static void Main(string[] args) { MyCollection col = new MyCollection(); Console.WriteLine("Values in the collection are:"); //顯示集合項 foreach(int i in col) { Console.WriteLine(i); } } }} 注:集合類(hashtable等)可以直接使用foreach方法。
3.跳轉語句1.break:可以終止距離它最近的封閉式循環結構或者條件語句的執行。2.continue:可以使程序執行它所在的封閉迭代語句的下一次迭代。3.goto語句1.goto語句使程序代碼直接轉至標記語句。2.goto語句的通常用法是:(1)使程序跳轉至特定的switch—case標簽 (2)用於跳出多層嵌套循環例子:switch (n) { case 1: cost += 25; break; case 2: cost += 25; goto case 1; case 3: cost += 50; goto case 1; default: Console.WriteLine("Invalid selection."); break; }(2)例子:using System;public class GotoTest1{ static void Main() { int x = 200, y = 4; int count = 0; string[,] array = new string[x, y];
// Initialize the array: for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++) array[i, j] = (++count).ToString();
// Read input: Console.Write("Enter the number to search for: ");
// Input a string: string myNumber = Console.ReadLine();
// Search: for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { if (array[i, j].Equals(myNumber)) { goto Found; } } }
Console.WriteLine("The number {0} was not found.", myNumber); goto Finish;
Found: Console.WriteLine("The number {0} is found.", myNumber);
Finish: Console.WriteLine("End of search."); }}
4.異常處理語句1.不要在try語句塊中對在try外部聲明的變量進行初始化,因為不能保證它一定會被執行。例子:Int x;Try{ x = 1;}Catch{}Console.Write(x);//////////////////錯誤!!!!!!!!!!!!
例子:try-catch語句,注意catch的順序很重要,要逐步擴大exception的范圍。using System;class MainClass{ static void ProcessString(string s) { if (s == null) { throw new ArgumentNullException(); } }
static void Main() { try { string s = null; ProcessString(s); } // Most specific: catch (ArgumentNullException e) { Console.WriteLine("{0} First exception caught.", e); } // Least specific: catch (Exception e) { Console.WriteLine("{0} Second exception caught.", e); } }}2.finally:用於清除在try塊中申請的資源,並且執行即使在發生異常時也必須執行的代碼。無論什么情況,finally語句都一定會執行!!!!!!!!!3.try-catch-finally:通常用法是在try塊中拋出異常並申請資源,在catch塊中捕獲異常處理異常,在finally塊中釋放資源。例子:uusing System;public class EHClass{ static void Main() { try { Console.WriteLine("Executing the try statement."); throw new NullReferenceException(); } catch (NullReferenceException e) { Console.WriteLine("{0} Caught exception #1.", e); } catch { Console.WriteLine("Caught exception #2."); } finally { Console.WriteLine("Executing finally block."); } }}5.checked和unchecked關鍵字1.checked:對整形算術運算符,和類型轉換提供溢出檢查。2.unchecked:用於取消對算術運算符和類型轉換的溢出檢查。此時,算法溢出會被忽略,並且結果會被截斷。3.編譯器默認的是checked。public int UncheckedAdd(int a, int b){ return unchecked(a + b);} 6.fixed語句1.fixed語句可以防止變量被垃圾回收器重新定位。2.只能在不安全的向下文中使用fixed。3.fixed語句可以設置指向托管變量的指針,並且在fixed語句塊執行期間鎖定該變量。當fixed語句結束,被鎖定的變量被取消鎖定,仍然受GC的管理。C#規定,只有在fixed語句中才可以設置指向托管變量的指針。5.無法修改在fixed語句中初始化的指針。6.在不安全模式下,可以在stack(線程堆棧)上分配內存,線程堆棧不受GC管理,所以不用,fixed鎖定。例子:using System;
class Point{ public int x, y; }
class FixedTest { // Unsafe method: takes a pointer to an int. unsafe static void SquarePtrParam (int* p) { *p *= *p; }
unsafe static void Main() { Point pt = new Point(); pt.x = 5; pt.y = 6; // Pin pt in place: fixed (int* p = &pt.x) ////fixed語句,不要指向fixed語句之外的那些////變量 { SquarePtrParam (p); } // pt now unpinned Console.WriteLine ("{0} {1}", pt.x, pt.y); }}7.lock語句1.lock語句:用於標記臨界區。方法是獲取給定對象的互斥鎖,在執行語句結束時,釋放該鎖。2.語法格式: Lock (Expression) statement_block;其中:expression 是要被鎖定的對象,它必須是引用類型。 通常,如果要保護實例變量(即lock用在類方法里),則expresson為this, 即用lock(this){ statement },如果要保護靜態變量,則expression為typeof(class)。注意:不要鎖定public對象,否則會出錯。最佳辦法是鎖定private對象。例子: using System;using System.Threading;
class Account{ private Object thisLock = new Object(); int balance;
Random r = new Random();
public Account(int initial) { balance = initial; }
int Withdraw(int amount) {
// This condition will never be true unless the lock statement // is commented out: if (balance < 0) { throw new Exception("Negative Balance"); }
// Comment out the next line to see the effect of leaving out // the lock keyword: lock(thisLock) { if (balance >= amount) { Console.WriteLine("Balance before Withdrawal : " + balance); Console.WriteLine("Amount to Withdraw : -" + amount); balance = balance - amount; Console.WriteLine("Balance after Withdrawal : " + balance); return amount; } else { return 0; // transaction rejected } } }
public void DoTransactions() { for (int i = 0; i < 100; i++) { Withdraw(r.Next(1, 100)); } }}
class Test{ static void Main() { Thread[] threads = new Thread[10]; Account acc = new Account(1000); for (int i = 0; i < 10; i++) { Thread t = new Thread(new ThreadStart(acc.DoTransactions)); threads[i] = t; } for (int i = 0; i < 10; i++) { threads[i].Start(); } }}
九.類型關鍵字C#中有三種類型:1.值類型2.引用類型3.指針類型值類型:1.結構:A.數值類型:整型,浮點型,decimal型 B.bool c.用戶自定義的結構結構類型:是一種值類型,用於封裝一組相關變量,可以包含構造函數,常量,字段,方法,屬性,索引器,運算符,事件,嵌套類型。 結構可以實現接口,但是不能實現繼承,其中的成員也不能聲明為protected。2.枚舉:using System;public class EnumTest { enum Range :long {Max = 2147483648L, Min = 255L}; static void Main() { long x = (long)Range.Max; long y = (long)Range.Min; Console.WriteLine("Max = {0}", x); Console.WriteLine("Min = {0}", y); }}注意:1.基於值類型的變量直接包含值。將一個值類型變量賦給另一個值類型變量時,將復制包含的值。這與引用類型變量的賦值不同,引用類型變量的賦值只復制對對象的引用,而不復制對象本身。2.所有的值類型均隱式派生自 System.ValueType。3.與引用類型不同,從值類型不可能派生出新的類型。但與引用類型相同的是,結構也可以實現接口。4.與引用類型不同,值類型不可能包含 null 值。然而,可空類型功能允許將 null 賦給值類型。 例如:Nullable <int> a = null;(但是只能判斷a是否等於null,不能將null作為輸出,否則引發異常)或int? a = null;4.每種值類型均有一個隱式的默認構造函數來初始化該類型的默認值。有關值類型默認值的信息。
1.bool關鍵字1.bool是System.Boolean的別名。2.轉換:不存在bool類型與其他任何類型的相互轉換。3.If()條件判斷時必須是bool類型的值。例如:int x = 1; if(x){}是錯誤的。必須將該變量於一個值進行顯示比較。2.byte關鍵字1.轉換:byte x = 10; 合法 Int a = 10; byte x = a; 不合法,目標量必須占有更大的存儲空間(byte是目標量),除非進行顯示類型轉換。3.char關鍵字4.demical關鍵字1.demical類型具有更高的精度和更小的范圍。適用於財務和貨幣計算。2.如果希望將實數視為demical類型。則在后面加上m或M。例如:demical d = 300.01m;5.double關鍵字1.默認情況下,等號右邊的實數將會被視為double類型。但是,要想將整數視為double類型,在后面加上d或者D。例如: double d = 3d;6.enum1.enum關鍵字用於聲明枚舉,enum類型是由一組稱為枚舉數列表的命名常量組成的特殊類型。2.每種枚舉類型均有一組基礎類型,此基礎類型可以是除char類型之外的任何整形。例子: using System;public class EnumTest { enum Range :long {Max = 2147483648L, Min = 255L};//基礎類型是long static void Main() { long x = (long)Range.Max; long y = (long)Range.Min; Console.WriteLine("Max = {0}", x); Console.WriteLine("Min = {0}", y); }}3.從枚舉類型到其他類型需要顯示的類型轉換(無論基礎類型是什么!)。.7.float關鍵字1.要想使實數變成float類型,后面加上f.例如:float f = 3.5f; 8.Int關鍵字9.long類型1.要想使整數變成long類型,在后面加上l或L。例如:long L = 64L;10.sbyte帶符號的byte類型。11.short類型帶符號的16位整數。12.struct關鍵字1.結構類型:是一種值類型,用於封裝一組相關變量,可以包含構造函數,常量,字段,方法,屬性,索引器,運算符,事件,嵌套類型。 結構可以實現接口,但是不能實現繼承,其中的成員也不能聲明為protected。2.struct是在stack上分配空間。3.結構類型對具有語意的小型結構尤為有用。4.聲明結構的默認構造函數(就是沒有參數的構造函數)是錯誤的。因為C#中已經提供了默認構造函數。5.在結構中初始化實例字段是錯誤的。13.uint關鍵字1.無符號32位整數。2.在整數后面加上u,即可以把整數變成無符號的數,根據其值的大小判斷是uint還是ulong。14.ulong關鍵字1.無符號64位整數。15.ushort關鍵字1.無符號16位整數。九.裝箱和取消裝箱1.裝箱1.對值類型裝箱會使之變為一個對象,會在heap(垃圾回收堆)上為其分配存儲空間,創建object對象,並將其值復制到對象。2.原始值類型和裝箱對象使用不同的內存,可以存儲不同的值。裝箱轉換 在heap上分配存儲空間創建新對象,是在stack上的object引用其值。(boxed)i和(unboxed)i存儲在不同內存中。class TestBoxing { static void Main() { int i = 123; object o = i; // implicit boxing i = 456; // change the contents of i
System.Console.WriteLine("The value-type value = {0}", i); System.Console.WriteLine("The object-type value = {0}", o); }}2.取消裝箱進行裝箱和取消裝箱都會進行大量計算,降低性能。1.取消裝箱是將object對象裝換成值類型。2.取消裝箱將執行下列操作: A.檢查該object對象,確保它是要轉換成的值類型的一個裝箱值。 B.將object對象的值復制到值類型對象中。3.要想成功取消裝箱,必須保證:(1)該object對象是某個值的引用,null不行。 (2)object對象必須是在對該值類型的值裝箱時創建的。 (3)取消裝箱必須是顯示的。取消裝箱轉換 例子:class TestUnboxing{ static void Main() { int i = 123; object o = i; // implicit boxing
try { int j = (short) o; // attempt to unbox System.Console.WriteLine("Unboxing OK."); } catch (System.InvalidCastException e) { System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message); } }}將short改成int就可以獲得Unboxing ok.3.引用類型1.引用類型變量又稱為對象,可以存儲對實際數據的引用。2.常用的引用類型:class,interface,delegate,object,string.1.class2.delegate3.interface1.接口的作用是定義某種合約,實現接口的類和結構必須遵守這種合約。2.一個接口可以繼承多個接口,接口本身並不向其中的成員提供實現,而是有繼承該接口的類和結構實現。3.當類繼承了類和接口時,類寫在前面。4.object1.object類基於system.object類。可以將任何類型的值賦予object類變量。2.所有數據,無論是預定義的還是用戶自定義的都繼承自object類。3.object類型是同對象進行拆裝箱的類型。5.string關鍵字1.string類型是引用類型,但是當使用==或!=進行比較時,比較的是應用的值,而不是引用本身。2.[]運算符用於訪問string中的個別字符。例如:char c = “abcdefd”[2]C的值是c.3.@符號:@”abcdefgh”用@符號的好處是換碼序列將不被處理。但是要想用雙引號,使用””abcd””的形式。例子:string str = @”””stop!””, he shout!”;
6.格式化輸出十一.屬性(Attribute)