- C# 中(不同于 C++)的變量,總是需要你在訪問它們前先進(jìn)行初
始化,否則你將遇到編譯時(shí)錯(cuò)誤。故而,不可能訪問未初始化的變量歌殃。 - 你不能在 C# 中訪問一個(gè)“掛起”指針。
- 超出數(shù)組邊界的表達(dá)式索引值同樣不可訪問蝙云。
- C# 中沒有全局變量或全局函數(shù),取而代之的是通過靜態(tài)函數(shù)和靜態(tài)
變量完成的氓皱。
C#之值類型和引用類型
一 、值類型和引用類型 異同
值類型引用就會(huì)報(bào)錯(cuò)勃刨,引用類型就不會(huì)
值類型沒有初始化波材,就沒有在內(nèi)存開辟空間
值類型 : 所有值類型均隱士派生與System.ValueType;
如:bool****型:bool(System.Boolean的別名);
枚舉:enum(派生于System.Enum)朵你;
可空類型(派生于System.Nullable泛型結(jié)構(gòu)體各聘,語(yǔ)法 T? 是 System.Nullable<T> 的簡(jiǎn)寫,此處的 T 為值類型抡医。)
**2.每種值類型均有一個(gè)隱式的默認(rèn)構(gòu)造函數(shù)來初始化該類型的默認(rèn)值躲因。
**例如:
int i = new int();
等價(jià)于:Int32 i = new Int32();
等價(jià)于:int i = 0;
等價(jià)于:Int32 i = 0;
使用new運(yùn)算符時(shí)早敬,將調(diào)用特定類型的默認(rèn)構(gòu)造函數(shù)并對(duì)變量賦以默認(rèn)值。在上例中大脉,默認(rèn)構(gòu)造函數(shù)將值0賦給了i搞监。
3.所有的值類型都是密封(seal)的,所以無(wú)法派生出新的值類型镰矿。
4.****值類型的實(shí)例通常是在線程棧上分配的(靜態(tài)分配)琐驴,但是在某些情形下可以存儲(chǔ)在堆中。
引用類型的特性:
1.****C#的所有引用類型均隱式派生自System.object秤标。
****各個(gè)引用類型及其基類:
****數(shù)組:(派生于System.Array)數(shù)組的元素绝淡,不管是引用類型還是值類型,都存儲(chǔ)在托管堆上苍姜;
類:class(派生于System.Object)牢酵;
接口:interface(接口不是一個(gè)“東西”,所以不存在派生于何處的問題衙猪。)馍乙;
委托:delegate(派生于System.Delegate);
object****:(System.Object的別名)垫释;
字符串:string(System.String的別名)丝格。
2.引用類型可以派生出新的類型。
3.引用類型可以包含null值棵譬。
4.****引用類型變量的賦值只復(fù)制對(duì)對(duì)象的引用显蝌,而不復(fù)制對(duì)象本身。
5.引用類型的對(duì)象總是在進(jìn)程堆中分配(動(dòng)態(tài)分配)茫船。
二 琅束、c#沒有全局變量,每一個(gè)c#文件都不會(huì)互相干擾嗎算谈?那么一個(gè)變量怎么互相引用涩禀?
你這說的是什么意思呀。C#怎么會(huì)沒有全局變量呢然眼,你如果只是不知道怎么可以在不同類之間互想調(diào)用變量值這還可以理解艾船。下面是我給你的分類:
全局變量可會(huì)為,同類下的全局變量即在一個(gè)類里定義
public class class1
{
public int 變量1;
public static int 變量2;
public const int 變量3;
public readonly int 變量4;
}
變量1的調(diào)用方法:只能通過class1實(shí)例調(diào)用高每。如 class1 test = new class1;
int class變量值 = test.變量1;(注意此時(shí)變量值要用關(guān)鍵字public/internal/protecd才可調(diào)用)具體這三個(gè)關(guān)鍵字的用法你可以去研究下屿岂。如是關(guān)鍵字是private 那就不能調(diào)用了。但可用變通的做法鲸匿∫常可以用屬性如可以在類里增加一個(gè)屬性來控制對(duì)變量的調(diào)用方式
public int 調(diào)用變量1
{
get{return this.變量1;}
private set{this.變量1 = value;}
}
這樣你可以把變量1用private關(guān)鍵字封閉起來,不讓用戶去修改或訪問它带欢。如果要知道他的值可以調(diào)用屬性 int class變量值 = test.調(diào)用變量1;獲得值运授。但無(wú)法修改這個(gè)變量值烤惊。除非在屬性中的刪除set的關(guān)鍵字private 這樣才可以在其它類里獲取或修改它的值。
變量2的調(diào)用方法:這種變量在程序加載之后即運(yùn)行時(shí)吁朦。系統(tǒng)就會(huì)事先定義此變量柒室。調(diào)用方法就是不管在何處都可以對(duì)它修改訪問 int 變量2值 = class.變量2; 在這里要注意正因?yàn)檫@個(gè)變量唯一只有一個(gè)不管理你class1創(chuàng)建了多少個(gè)實(shí)例其變量2的值也只有一份。不會(huì)多也不會(huì)少逗宜。以下的另個(gè)變量也是這樣的只是其他兩種變量不可修改雄右。如果對(duì)變量2進(jìn)行修改的話要注意在多線程的線程沖突。因?yàn)榇俗兞恐挥幸环萑绻渲幸粋€(gè)線程正在修改還沒有完成而另一個(gè)線程確來訪問變量值就有可以得到不正確的值纺讲。
變量3與變量4的調(diào)用方法:與變量2相同只是不能修改擂仍。兩者唯一不同的是值存放的形式的不同
變量3在編譯時(shí)是直接將值的給對(duì)方的調(diào)用方。而變量4是在運(yùn)行時(shí)才把最終的值給調(diào)用方刻诊。其中利弊可以自己權(quán)衡防楷。
三、C#中靜態(tài)函數(shù)的作用
public static void haha()與public void haha()有什么區(qū)別~~
class Test
{
public static void A方法()
public voidB方法()
}
在調(diào)用的時(shí)候,如果我要調(diào)用 A方法只需這樣調(diào)用:Test.A方法()如果要調(diào)用B方法這樣調(diào)用Test ts = new Test();ts.B方法靜態(tài)方法的好處就是你無(wú)需new(也就是實(shí)例化)那個(gè)Test類.
靜態(tài)變量使用 static 修飾符進(jìn)行聲明则涯,在類被實(shí)例化時(shí)創(chuàng)建,通過類進(jìn)行訪問不帶有 static 修飾符聲明的變量稱做非靜態(tài)變量冲簿。
static變量在對(duì)象被實(shí)例化時(shí)創(chuàng)建粟判,通過對(duì)象進(jìn)行訪問一個(gè)類的所有實(shí)例的同一C#靜態(tài)變量都是同一個(gè)值,同一個(gè)類的不同實(shí)例的同一非靜態(tài)變量可以是不同的值峦剔。
靜態(tài)函數(shù)的實(shí)現(xiàn)里不能使用非靜態(tài)成員档礁,如非靜態(tài)變量、非靜態(tài)函數(shù)等吝沫。
class StaticTest{
static int x = 0; int y = 0;
public void SetX(int a) { x = a; }
public void SetY(int a) { y = a; }
public void Print() {
Console.WriteLine("x = {0} y = {1}", x, y);
}
static void Main(string[] args) {
StaticTest st = new StaticTest();
StaticTest st1 = new StaticTest();
st.SetX(10); //將10賦給x呻澜;
st.SetY(10); //將10賦給y;
st.Print(); //顯示:x=10 y=10
st1.SetX(20); //將20賦給x
st1.SetY(20); //將20賦給x
st1.Print(); //顯示:x=20 y=20
st.Print(); //由于x是靜態(tài)變量惨险,所以在此調(diào)用第一次初始化實(shí)例st時(shí)羹幸,靜態(tài)變量已經(jīng)變?yōu)?0, 輸出:x=20 y=10
st.SetX(30);
st.SetY(30);
st.Print();
//由于x是靜態(tài)變量辫愉,所以在此調(diào)用初始化實(shí)例st時(shí)栅受,靜態(tài)變量已經(jīng)變?yōu)?0, 輸出:x=30 y=30
st1.Print();
//由于x是靜態(tài)變量恭朗,所以在此調(diào)用st1實(shí)例時(shí)屏镊,靜態(tài)變量已經(jīng)變?yōu)?0, 輸出:x=30 y=20
}
}
靜態(tài)類:
聲明為static痰腮,它僅包含靜態(tài)成員而芥,不能用new靜態(tài)類的實(shí)例。使用靜態(tài)類來包含不與特定對(duì)象關(guān)聯(lián)的方法膀值。
功能:僅包含靜態(tài)成員棍丐,不能被實(shí)例化误辑,是密封的,不能包含實(shí)例構(gòu)造函數(shù)骄酗,可包含靜態(tài)構(gòu)造函數(shù)以分配初始值或設(shè)置某個(gè)靜態(tài)變量稀余。
優(yōu)點(diǎn):編譯器能夠執(zhí)行檢查以確保不致偶然地添加勢(shì)力成員。編譯器將保證不會(huì)創(chuàng)建此類的實(shí)例趋翻。
靜態(tài)類是不能實(shí)例化的睛琳,我們直接使用它的屬性與方法,靜態(tài)類最大的特點(diǎn)就是共享踏烙。
探究
public static class StaticTestClass{
public static int n = 0;
public static void Add() {
n++;
}
}
網(wǎng)頁(yè) P1.aspx 調(diào)用 StaticTestClass.Add()师骗,并在頁(yè)面上輸出 n。
網(wǎng)頁(yè) P2.aspx 調(diào)用 StaticTestClass.Add()讨惩,并在頁(yè)面上輸出 n辟癌。
訪問者 V1 從客戶端 C1 訪問 P1.aspx,此時(shí)輸出為 1荐捻。
訪問者 V2 從客戶端 C2 訪問 P2.aspx黍少,此時(shí)輸出為 2。
訪問者 V1 關(guān)閉瀏覽器处面,重新打開訪問 P1.aspx厂置,此時(shí)輸出為 3。
靜態(tài)方法:
是一種特殊的成員方法魂角,不屬于類的某一個(gè)具體的實(shí)例昵济。非靜態(tài)方法可以訪問類中的任何成員,而靜態(tài)只能訪問類中的靜態(tài)成員野揪。
靜態(tài)構(gòu)造函數(shù):
class SimpleClass{
// Static constructor
static SimpleClass() {
}}
一個(gè)類只能有一個(gè)靜態(tài)構(gòu)造函數(shù)访忿,該構(gòu)造函數(shù)不能有訪問修飾符,不能帶任何參數(shù)斯稳,不能直接調(diào)用海铆,只能在:
1 創(chuàng)建包含靜態(tài)構(gòu)造函數(shù)的類實(shí)例時(shí)
2 訪問包含靜態(tài)構(gòu)造函數(shù)的靜態(tài)成員時(shí)
會(huì)先調(diào)用靜態(tài)構(gòu)造函數(shù),無(wú)論創(chuàng)建了多少個(gè)類實(shí)例平挑,其靜態(tài)構(gòu)造函數(shù)都只調(diào)用了一次游添。
用于對(duì)靜態(tài)字段、只讀字段等的初始化通熄。
添加static關(guān)鍵字唆涝,不能添加訪問修飾符,因?yàn)殪o態(tài)構(gòu)造函數(shù)都是私有的唇辨。
類的靜態(tài)構(gòu)造函數(shù)在給定應(yīng)用程序域中至多執(zhí)行一次:只有創(chuàng)建類的實(shí)例或者引用類的任何靜態(tài)成員才激發(fā)靜態(tài)構(gòu)造函數(shù)
靜態(tài)構(gòu)造函數(shù)是不可繼承的廊酣,而且不能被直接調(diào)用。
如果類中包含用來開始執(zhí)行的 Main 方法赏枚,則該類的靜態(tài)構(gòu)造函數(shù)將在調(diào)用 Main 方法之前執(zhí)行亡驰。任何帶有初始值設(shè)定項(xiàng)的靜態(tài)字段晓猛,則在執(zhí)行該類的靜態(tài)構(gòu)造函數(shù)時(shí),先要按照文本順序執(zhí)行那些初始值設(shè)定項(xiàng)凡辱。
如果沒有編寫靜態(tài)構(gòu)造函數(shù)戒职,而這時(shí)類中包含帶有初始值設(shè)定的靜態(tài)字段,那么編譯器會(huì)自動(dòng)生成默認(rèn)的靜態(tài)構(gòu)造函數(shù)透乾。
C#靜態(tài)方法及屬性在程序啟動(dòng)的時(shí)候洪燥,就全部裝入內(nèi)存的,而不管這些方法乳乌、屬性以后有沒有用到捧韵。即使是沒有人再訪問程序,這部分內(nèi)存仍然不會(huì)釋放還有就是汉操,所有訪問者看到的靜態(tài)屬性的數(shù)據(jù)幾乎都是一樣的再来,比如A用戶設(shè)置了UserName這個(gè)屬性,B用戶訪問的時(shí)候磷瘤,得到的UserName仍然是A用戶設(shè)置的那個(gè)芒篷。這種特性,如果用在固定數(shù)據(jù)中采缚,那不會(huì)有太大問題梭伐,比如連接字符串之類的
C#靜態(tài)方法/數(shù)據(jù)成員是屬于類的,不是屬于某一個(gè)對(duì)象的仰担,因而調(diào)用它不需要實(shí)例化;靜態(tài)方法和靜態(tài)數(shù)據(jù)成員相當(dāng)于共享變量绩社。為該類的所有對(duì)象所共有摔蓝,因而在需要共享數(shù)據(jù)時(shí),定義這種類型時(shí)很好的選擇愉耙。 一但定義一個(gè)類后(不一定要實(shí)例化對(duì)象)該類的所有靜態(tài)成員就載入內(nèi)存(并不是程序啟動(dòng)贮尉,就裝入內(nèi)存,沒有定義該類時(shí)它不會(huì)載入內(nèi)存) 靜態(tài)成員的作用域與它所屬的類的作用域相同