C# 基礎(chǔ)

  • C#由微軟開發(fā)舟误,并由ECMA和ISO核準(zhǔn)認(rèn)可石挂。
  • C#由Anders Hejlsberg和他的團隊在.NET框架期間開發(fā)的
  • C#專為公共語言基礎(chǔ)結(jié)構(gòu)(CLI)設(shè)計的竿裂,CLI由可執(zhí)行代碼和運行時環(huán)境組成矩父,允許在不同計算機平臺和體系結(jié)構(gòu)上使用各種高級語言没龙。
  • 集成開發(fā)環(huán)境IDE:編輯=>編譯=>調(diào)試=>發(fā)布
  • 學(xué)習(xí)路徑:語言=>類庫=>框架

功能

  • C#的構(gòu)想接近于C和C++奢赂,是一門面向?qū)ο蟮木幊陶Z言唱遭,并與Java非常相似。
  • .NET 指 .Net Framework框架 是一種平臺呈驶、技術(shù)
  • C# 可以開發(fā)基于.Net平臺的應(yīng)用

.Net開發(fā)領(lǐng)域

  • 桌面應(yīng)用程序 WinForm
  • Internet應(yīng)用程序 WebService/ASP.NET
  • 手機開發(fā) WP7

網(wǎng)絡(luò)架構(gòu)模式

  • B/S
    瀏覽器(Browser)/服務(wù)器(Server)模式
  • C/S
    客戶端(Client)/服務(wù)端(Server)模式
    桌面開發(fā)(WinForm)的網(wǎng)絡(luò)應(yīng)用程序拷泽,如飛秋恩沽、QQ等

環(huán)境

C#是.NET框架的一部分底扳,且用于編寫.NET應(yīng)用程序奏赘。

.NET框架是一個創(chuàng)新的平臺腿堤,能編寫Windows應(yīng)用程序琼懊、Web應(yīng)用程序姐帚、Web服務(wù)旦部。.NET由一個巨大的代碼庫組成在扰,用于C#等客戶端語言霉晕。

路線

.NET學(xué)習(xí)路線

入門

# 編寫源代碼
$ vim app.cs

// using關(guān)鍵字用于在程序中包含System命名空間
using System;
// 命名空間聲明
namespace Application
{
    // 類聲明:程序的最小單元
    class Klass
    {
        // 入口點方法:主函數(shù)
        static void Main(string[] args)
        {
            // 在屏幕上顯示消息庭再,WriteLine是定義在System命名空間下Consolle類的方法
            Console.WriteLine("Hello World");//命令:以分號結(jié)束
            // 針對VS.NET,程序會等待一個按鍵動作牺堰,防止程序從VS.NET啟動時屏幕會快速運行并關(guān)閉拄轻。
            Console.ReadKey();
//F5調(diào)試運行 Ctrl+F5不調(diào)試直接運行 
        }
    }
}

# 編譯源代碼
$ csc app.cs
Microsoft (R) Visual C# Compiler version 4.7.3056.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.

This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240

# 生成可執(zhí)行文件
$ ls
app.cs app.exe

# 執(zhí)行程序
$ app.exe
Hello World
將.NET添加入系統(tǒng)環(huán)境變量

代碼剖析

  • 類class是構(gòu)成程序的主體
  • 命名空間namespace以樹型結(jié)構(gòu)組織類
  • C#是大小寫敏感的
  • 語句和表達(dá)式以分號結(jié)尾
  • 程序的執(zhí)行從Main()方法開始
  • 與Java不同的是,文件名可以不同于類名伟葫。

類庫的引用

  • DLL引用 黑盒引用
  • 項目引用 白盒引用

語法

$ vim rect.cs

using System;
namespace RectangleApp
{
    class Rectangle
    {
        double length;
        double width;
        
        public void AcceptDetails()
        {
            length = 1.5;
            width = 3;
        }
        
        public double GetArea()
        {
            return length * width;
        }
        
        public void Display()
        {
            Console.WriteLine("Length:{0}", length);
            Console.WriteLine("Width:{0}", width);
            Console.WriteLine("Area:{0}", GetArea());
        }
    }
    
    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            Rectangle rect = new Rectangle();
            rect.AcceptDetails();
            rect.Display();
            Console.ReadLine();
        }
    }
}

$ csc rect.cs
$ rect.exe
Length:1.5
Width:3
Area:4.5

從程序中輸出文本

Console.WriteLine(格式字符串(含替代標(biāo)記)恨搓, 替換值0, 替換值1...)

System命名空間中的Console類提供ReadLine()函數(shù),用于接收來自用戶的輸入,并將其存儲到一個變量中斧抱。

int num;
num = Convert.ToInt32(Console.ReadLine());

標(biāo)識符

用于識別類常拓、變量、函數(shù)或任何其它用戶定義的項目辉浦。

標(biāo)識符
  • 標(biāo)識符必須以字母弄抬、下劃線、@開頭宪郊,后跟字母掂恕、數(shù)字、下劃線废膘、@。
  • 標(biāo)識符第一個字符不能是數(shù)字
  • 標(biāo)識符必須不包含任何嵌入的空格或符號
  • 標(biāo)識符不能是C#關(guān)鍵字慕蔚,除非有@前綴丐黄。
  • 標(biāo)識符必須區(qū)分大小寫
  • 不能與C#類庫名稱相同
  • @字符只能放在標(biāo)識符首位,不推薦將@作為常用字符孔飒。

關(guān)鍵字

關(guān)鍵字是C#編譯器預(yù)定義的保留字灌闺,不能作為標(biāo)識符。關(guān)鍵字分為保留關(guān)鍵字(Reserved Keywords) 和上下文關(guān)鍵字(Contextual Keywords)坏瞄。

  • 上下文關(guān)鍵字是僅在特定的語言結(jié)構(gòu)中充當(dāng)關(guān)鍵字的標(biāo)識符
上下文關(guān)鍵字

關(guān)鍵字約定

  • 關(guān)鍵字全部由小寫字母組成
  • 關(guān)鍵字不能用作變量名或任何其他形式的標(biāo)識符桂对,除非以@字符開始。

堆棧

程序運行時鸠匀,數(shù)據(jù)必須存儲在內(nèi)存中蕉斜。一個數(shù)據(jù)項需要多大內(nèi)存、存儲在什么地方缀棍、如何存儲都依賴于該數(shù)據(jù)項的類型宅此。運行中的程序使用兩個內(nèi)存區(qū)域來存儲數(shù)據(jù):棧和堆。

棧是一個內(nèi)存數(shù)組爬范,是一個LIFO(Last-In First-Out父腕,后進(jìn)先出)的數(shù)據(jù)結(jié)構(gòu)。

棧存儲幾種類型的數(shù)據(jù)

  • 某些類型變量的值
  • 程序當(dāng)前的執(zhí)行環(huán)境
  • 傳遞給方法的參數(shù)

棧的特征

  • 數(shù)據(jù)只能從棧的頂端插入和刪除
  • 把數(shù)據(jù)放到棧頂成為入棧(push)
  • 從棧頂刪除數(shù)據(jù)成為出棧(pop)
入棧出棧

堆是一塊內(nèi)存區(qū)域青瀑,在堆里可以分配大塊的內(nèi)存用于存儲某類型的數(shù)據(jù)對象璧亮。與棧不同,堆里的內(nèi)存能夠以任意順序存入和移除斥难。

內(nèi)存堆

程序可在堆中存儲數(shù)據(jù)枝嘶,但并不能顯式地刪除。CLR的自動GC(Garbage Collector哑诊,垃圾收集器)在判斷出程序的代碼將不會再訪問某數(shù)據(jù)項時躬络,自動清除無主的堆對象。

堆中的自動垃圾收集

類型

  • C程序是一組函數(shù)和數(shù)據(jù)類型
  • C++程序是一組函數(shù)和類
  • C#程序是一組類型聲明

C# 程序是一組類型聲明

  • C#程序或DLL的源代碼是一組一種或多種類型聲明
  • 對于可執(zhí)行程序搭儒,類型聲明中必須有一個包含Main方法的類穷当。
  • 命名空間是一種把相關(guān)的類型聲明分組并命名的方法

C# 程序是一組類型聲明提茁,學(xué)習(xí)C#就是學(xué)習(xí)如何創(chuàng)建和使用類型。什么是類型呢馁菜,可將它想象成一個用來創(chuàng)建數(shù)據(jù)結(jié)構(gòu)的模板茴扁。模板本身并不是數(shù)據(jù)結(jié)構(gòu),但它詳細(xì)說明了由該模板構(gòu)造的對象的特性汪疮。

類型的組成元素

  • 名稱
  • 用來保存數(shù)據(jù)成員的數(shù)據(jù)結(jié)構(gòu)
  • 行為和約束條件
類型是一種模板

實例化類型

從某個類型模板創(chuàng)建實際的對象峭火,稱為實例化該類型。

  • 通過實例化類型而創(chuàng)建的對象被稱為類型的對象或?qū)嵗?/li>
  • C#程序中智嚷,每個數(shù)據(jù)項都是某種類型的實例卖丸。
通過實例化類型創(chuàng)建實例

預(yù)定義類型

預(yù)定義類型

數(shù)據(jù)項的類型定義了存儲數(shù)據(jù)需要的內(nèi)存大小與組成該類型的數(shù)據(jù)成員。類型還決定了對象在內(nèi)存中的存儲位置 - 堆或棧盏道。

類型被分為兩種:值類型和引用類型稍浆,兩種類型的對象在內(nèi)存中的存儲方式不同。

數(shù)據(jù)類型
  • 值類型 Value types
    僅需一段單獨的內(nèi)存猜嘱,用于存儲實際的數(shù)據(jù)衅枫。
值類型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// 命名空間
namespace ConsoleApp
{
    //枚舉類型需放在類class之外,才能被其它類調(diào)用
    //枚舉類型:限定變量的可能值朗伶,其對應(yīng)的是整型數(shù)值弦撩,默認(rèn)從0開始。
    enum Weekday { Monday, Tuesday, Wenesday }
    //枚舉類型:可定義帶數(shù)字的枚舉類型
    enum Color {Red = 1, Blue = 2, Green = 3};


    //類:程序的最小單元
    class Program
    {
        //struct和enum均為值類型论皆,存儲在內(nèi)存的棧上益楼。
        //結(jié)構(gòu)體
        struct Person
        {
            public int age;
            public string name;
            public string firstName;
            public string lastName;
        }


        //程序入口:主函數(shù)
        static void Main(string[] args)
        {
            //所有類型均繼承自 System.Object
            object obj = null;

            //值類型 繼承自 System.ValueType
            int i1 = 0;   
            System.Int32 i2 = 10;

            //變量小寫,必須預(yù)先聲明類型
            bool flag = true;
            float f = 1.23f;

            //變量轉(zhuǎn)換
            string str = "hello";
            //short s = (short)str;
            //string str1 = Convert.ToString(f);

            //調(diào)用結(jié)構(gòu)
            Person person = new Person();
            person.age = 20;
            person.name = "junchow";

            //使用枚舉
            var day = Weekday.Tuesday;
            Console.WriteLine(Weekday.Monday);
            Console.ReadLine();

        }
    }
}
  • 引用類型 Reference types
    需要兩段內(nèi)存点晴,第一段存儲實際的數(shù)據(jù)偏形,位于堆中。第二段是一個引用觉鼻,指向數(shù)據(jù)在堆中的存放位置俊扭。
引用類型
  • 指針類型 Pointer types
    指針類型存儲另一種類型的內(nèi)存地址,C#的指針與C或C++中的指針有相同的功能坠陈。
// 聲明指針類型
type* identifier;
// 例如
char* cptr;
int * iptr;

C#中沒有全局變量的概念萨惑,所有的變量必須由該類的實例進(jìn)行操作,這樣做提升了安全性仇矾,但某些情況下卻顯得力不從心庸蔼。因此,在保存類的公共信息時贮匕,會使用靜態(tài)變量姐仅。

# 在變量前添加static關(guān)鍵字即可聲明為靜態(tài)變量
static <data_type> <variable_name> = value;

值類型

值類型變量可直接分配給一個值,從System.ValueType中派生,最終繼承自System.Object掏膏,值類型直接包含數(shù)據(jù)劳翰。

預(yù)定義類型
$ vim size.cs
using System;
namespace DatatypeApp
{
    class App
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Size of bool:{0}", sizeof(bool));
            Console.WriteLine("Size of byte:{0}", sizeof(byte));
            Console.WriteLine("Size of char:{0}", sizeof(char));
            Console.WriteLine("Size of decimal:{0}", sizeof(decimal));
            Console.WriteLine("Size of double:{0}", sizeof(double));
            Console.WriteLine("Size of float:{0}", sizeof(float));
            Console.WriteLine("Size of int:{0}", sizeof(int));
            Console.WriteLine("Size of long:{0}", sizeof(long));
            Console.WriteLine("Size of sbyte:{0}", sizeof(sbyte));
            Console.WriteLine("Size of short:{0}", sizeof(short));
            Console.WriteLine("Size of uint:{0}", sizeof(uint));
            Console.WriteLine("Size of ulong:{0}", sizeof(ulong));
            Console.WriteLine("Size of ushort:{0}", sizeof(ushort));
            Console.ReadLine();
        }
    }
}
$ csc size.cs
$ size.exe
Size of bool:1
Size of byte:1
Size of char:2
Size of decimal:16
Size of double:8
Size of float:4
Size of int:4
Size of long:8
Size of sbyte:1
Size of short:2
Size of uint:4
Size of ulong:8
Size of ushort:2

如需得到一個類型或一個變量在特定平臺上的準(zhǔn)確尺寸,可使用sizeof()馒疹。表達(dá)式sizeof(type)產(chǎn)生以字節(jié)為單位存儲對象或類型的存儲尺寸佳簸。

引用類型

引用類型不包含存儲在變量中的實際數(shù)據(jù),包含的是對變量的引用颖变。它們指向的是一個內(nèi)存位置生均。使用多個變量時,引用類型可指向一個內(nèi)存位置腥刹。若內(nèi)存位置的數(shù)據(jù)是由一個變量改變的马胧,其他變量會自動反映這種值的變化。內(nèi)置的引用類型有object衔峰、dynamic佩脊、string。

引用類型

C#內(nèi)置引用類型分為object朽色、string邻吞、dynamic

對象類型

對象類型是C#通用類型系統(tǒng)(Common Type System - CTS)中所有數(shù)據(jù)類型的終極基類组题。Object是System.Object類的別名葫男。所以對象類型可以被分配任何其他類型的值。在分配之前崔列,需先進(jìn)行類型轉(zhuǎn)換梢褐。

Object終極基類,是CLR運行時定義的最基礎(chǔ)的類型赵讯,CLR運行時要求所有類型盈咳,不管是系統(tǒng)定義的類型,還是自定義的類型边翼,都必須從Object類派生鱼响。

注意:一個值類型轉(zhuǎn)換為對象類型時被稱為裝箱,但一個對象類型被轉(zhuǎn)換為值類型時被稱為拆箱组底。

由于所有類型都從System.Object類型派生而來丈积,所以每個類型的每個對象實例均有一組最基本的方法。

  • Equals 虛方法债鸡,若兩個對象具有相同的值江滨,則返回 true。
[__DynamicallyInvokable]
public virtual bool Equals(object obj)
{
  return RuntimeHelpers.Equals(this, obj);
}
  • ToString 虛方法厌均,默認(rèn)返回類型的完整名稱
this.GetType().FullName
  • GetHashCode 虛方法唬滑,返回對象值得哈希值
  • GetType
    返回從Type派生的一個類型的實例,指出調(diào)用GetType的對象是什么類型,返回的Type對象和反射類配合晶密,可獲取對象類型相關(guān)元數(shù)據(jù)信息擒悬。
    GetType并非虛方法,目的是防止類重寫該方法惹挟,隱瞞其類型以破壞類型的安全性茄螃。
object obj1 = new object();//小寫objecct是System.Object類的別名
object obj2 = new Object();
Console.WriteLine(obj1.GetType());//System.Object
Console.WriteLine(obj1.ToString());//System.Object
Console.ReadLine();

字符串類型

字符串類型運行為變量分配任何字符串值,字符串類型stringSystem.String類的別名连锯,它是從對象類型object派生的归苍。字符串類型的值可通過兩種形式分配:引號和@引號。

String str = "hi"

@"hi"

C#的字符串類型前可添加@(稱作“逐字字符串”)將轉(zhuǎn)義字符\當(dāng)作普通字符對待运怖。

string str = @"C:\Windows";

string str = "C:\\Windows";

@字符串中可任意換行拼弃,換行符、縮進(jìn)空格都計算在字符串長度之內(nèi)摇展。

C#中字符串一旦創(chuàng)建就不可以更改長度大小吻氧,每次使用System.String類中方法時,都要在內(nèi)存中創(chuàng)建新的字符串對象咏连,也就是說每次都要為新對象分配空間盯孙。在需要對字符串執(zhí)行重復(fù)修改的情況下,與創(chuàng)建新的String對象相關(guān)的系統(tǒng)開銷可能會非常昂貴祟滴。

//分配固定內(nèi)存大小
string controllername = "User";
//創(chuàng)建新的內(nèi)存分配給controllername振惰,代價昂貴。
controllername += "Controller";

如果要修改字符串而非創(chuàng)建新的對象則可使用System.Text.StringBuilder類垄懂,例如:當(dāng)在一個循環(huán)中將許多字符串連接起來時骑晶,此時可提升性能。

//指定分配大小草慧,當(dāng)指定分配大小后性能會提升桶蛔。
StringBuilder sb = new StringBuilder(20);
//分配到堆區(qū)
sb.Append("User");
//不會被銷毀直接追加
sb.Append("Controller");

String聲明后在內(nèi)存中大小是不可以修改的,使用StringBuilder則可自由擴展大小漫谷,原因String分配在棧區(qū)仔雷,StringBuilder則分配在堆區(qū)。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{                    
    class Program
    {                   
        static void Main(string[] args)
        {
            Stopwatch timer = new Stopwatch();
            timer.Start();

            //string str = string.Empty;
            //for(int i=0; i<100000; i++)
            //{
            //    str += i.ToString(); //elapsed milliseconds : 16563
            //}

            StringBuilder sb = new StringBuilder();
            for(int i=0; i<100000; i++)
            {
                sb.Append(i.ToString());//elapsed milliseconds : 14
            }

            timer.Stop();
            Console.WriteLine("elapsed milliseconds : {0}", timer.ElapsedMilliseconds);
            Console.ReadLine();
        }
    }
}

用戶定義類型

  • 類類型 class
  • 結(jié)構(gòu)類型 struct
  • 數(shù)組類型 array
  • 枚舉類型 enum
  • 委托類型 delegate
  • 接口類型 interface

類型通過類型聲明創(chuàng)建

  • 要創(chuàng)建的類型的種類
  • 新類型的名稱
  • 對類型中每個成員的聲明(名稱和規(guī)格)

動態(tài)類型

動態(tài)類型可存儲任何類型的值在動態(tài)數(shù)據(jù)類型變量中舔示,這些變量的類型檢查時在運行時發(fā)生的碟婆。

# 聲明動態(tài)類型
dynamic <variable_name> = value;
# 例如
dynamic variable = 20;

動態(tài)類型與對象類型相似,對象類型變量的類型檢查時在編譯時發(fā)生的斩郎,動態(tài)類型變量的類型檢查時在運行時發(fā)生的脑融。

靜態(tài)類型

每個變量都包括變量類型,編譯器可以確定運行時需要的內(nèi)存容量以及那些部分應(yīng)該存放在棧上缩宜,哪些部分應(yīng)該存放在堆上肘迎。變量的類型在編譯時確定甥温,并且不能再運行時修改,這叫靜態(tài)類型妓布。

可空類型

某些情況下姻蚓,特別是使用數(shù)據(jù)庫時,希望表示變量目前未保存有效的值匣沼。對于引用類型很簡單狰挡,可見變量設(shè)置為null。但定義值類型的變量時释涛,不管它的內(nèi)容是否有效加叁,內(nèi)存都會進(jìn)行分配。

對于這種情況唇撬,可能會使用一個布爾指示器來和變量關(guān)聯(lián)它匕,如果值有效則設(shè)置為true否則設(shè)置為false

可空類型運行創(chuàng)建可以標(biāo)記為有效或無效的值類型窖认,在使用之前確定值得有效性豫柬。普通的值類型成為非可空類型。

using System;
namespace NullApp
{
    class Nullable
    {
        static void Main(string[] args)
        {
            // ?單問號
            // 用于對int扑浸、double烧给、bool等無法直接賦值為null的數(shù)據(jù)進(jìn)行null的賦值。
            int? n = 1;
            // 意思是此數(shù)據(jù)是Nullable可空類型的
            Nullable<int> m = new Nullable<int>(1);
            Console.WriteLine("n = {0}, m = {1}", n, m);
            
            // 可空類型
            // C#提供了一個特殊的數(shù)據(jù)類型nullable可空類型
            // 可空類型可以表示其基礎(chǔ)值類型正常范圍內(nèi)的值喝噪,再加上一個null值础嫡。
            // 在處理數(shù)據(jù)庫和其他包含可能未賦值的元素的數(shù)據(jù)類型時
            // 將null復(fù)制給數(shù)值類型或布爾類型的功能特別有用
            int? i = null;
            int? j = 1;
            double? x = new double?();
            double? y = 3.14;
            // 數(shù)據(jù)庫中的布爾型字段可存儲值true或false或者該字段也可以未定義
            bool? flag = new bool?();
            Console.WriteLine("i={0}, j={1}, x={2}, y={3}, flag={4}", i, j, x, y, flag);
            
            // Null合并運算符??
            // Null合并運算符用于定義可空類型和引用類型的默認(rèn)值
            double? a = null;
            Console.WriteLine("a = {0}", a ?? 1.1);
            // Null合并運算符為類型轉(zhuǎn)換定義了一個預(yù)設(shè)值,以防止可能類型的值Null仙逻。
            // Null合并運算符把操作數(shù)類型隱式轉(zhuǎn)換為另一個可空或非空的值類型的操作數(shù)的類型
            // 如果第一個操作數(shù)的值為空驰吓,則運算符返回第二個操作數(shù)的值涧尿,否則返回第一個操作數(shù)的值系奉。
            double? b = 1.23;
            Console.WriteLine("b = {0}", b ?? 3.21);
            
            Console.ReadLine();
        }
    }
}

類型轉(zhuǎn)換

類型轉(zhuǎn)換從根本上說是類型鑄造,或者說是把數(shù)據(jù)從一種類型轉(zhuǎn)換為另一種類型姑廉。

C#中缺亮,類型鑄造有兩種形式

  • 隱式類型轉(zhuǎn)換

隱式類型轉(zhuǎn)換是C#默認(rèn)的以安全方式進(jìn)行的轉(zhuǎn)換,不會導(dǎo)致數(shù)據(jù)丟失桥言。例如萌踱,從小范圍的整形轉(zhuǎn)換為大范圍的整形,從派生類轉(zhuǎn)換為基類号阿。

int i = 1;
double d = 1.1;

int n = i + d;//錯誤:無法將類型double隱式地轉(zhuǎn)換為int

當(dāng)高精度數(shù)據(jù)類型與低精度數(shù)據(jù)類型進(jìn)行運算時并鸵,定義運算結(jié)果的變量類型必須與高精度的變量類型保持一致,以防止在運算過程中造成數(shù)據(jù)丟失扔涧。

  • 顯式類型轉(zhuǎn)換

顯示類型轉(zhuǎn)換即強制類型轉(zhuǎn)換园担,顯示轉(zhuǎn)換需要強制轉(zhuǎn)換運算符届谈,且強制轉(zhuǎn)換會造成數(shù)據(jù)丟失。

$ vim conv.cs
using System;
namespace TypeConversionApp
{
    class Explicit
    {
        static void Main(string[] args)
        {
            double d= 123.456;
            int i;
            
            i = (int)d;
            Console.WriteLine("d={0}, i={1} ", d, i);
            Console.ReadKey();
        }
    }
}
$ cs conv.cs
$ conv.exe
d=123.456, i=123

變量

  • 變量是一個名稱弯汰,表示程序執(zhí)行時存儲在內(nèi)存中的數(shù)據(jù)艰山。

變量是一個供程序操作的存儲區(qū)的名字。C#中每個變量都有一個特定的類型咏闪,類型決定了變量的內(nèi)存大小和布局曙搬。范圍內(nèi)的值可存儲在內(nèi)存中,可對變量進(jìn)行一系列操作鸽嫂。

class Test
{
    static void Main()
    {
        string username;
        System.Console.Write("username: ");
        username = System.Console.ReadLine();
        System.Console.WriteLine("your username is {0}", username);
    }
}

變量習(xí)慣采用駝峰法Camel命名纵装,即大小寫形式。

C#提供4種變量

  • 本地變量
    在方法的作用域內(nèi)保存的臨時變量据某,不是類型的成員搂擦。
  • 字段
    保存和類型或類型實例相關(guān)的數(shù)據(jù),是類型的成員哗脖。
  • 參數(shù)
    用于從一個方法到另一個方法傳遞數(shù)據(jù)的臨時變量瀑踢,不是類型的成員。
  • 數(shù)組元素
    同類數(shù)據(jù)項構(gòu)成的有序集合的一個成員才避,可以是本地變量橱夭,也可以是類型的成員。
# 變量定義
<data_type> <variable_list>;

# 示例
int i,j,k;
char c,ch;
float f;
double d;

# 變量定義時初始化
int n = 1;

變量聲明

變量使用前必須聲明桑逝,變量聲明定義了變量棘劣,并完成兩件事情。

  • 給變量命名楞遏,并為它關(guān)聯(lián)一種類型茬暇。
  • 讓編譯器為它分配一塊內(nèi)存
變量聲明
變量聲明

變量初始化(variable initializer)

除聲明變量的名稱和類型外,聲明還能將它的內(nèi)存初始化為一個明確的值寡喝。

# 變量通過在等號后跟一個常量表達(dá)式進(jìn)行初始化(賦值)
variable_name = value;

# 變量可在聲明時被初始化糙俗,即指定一個初始值。
<data_type> <variable_name> = value;

正確地初始化變量是一個良好的編程習(xí)慣预鬓,否則有時程序會產(chǎn)生意想不到的結(jié)果巧骚。

$ vim def.cs
using System;

namespace VariableDefinition
{
    class Program{
        static void Main(string[] args)
        {
            short s;
            int i;
            double d;
            
            s = 1;
            i = 10;
            d = s + i;
            Console.WriteLine("s = {0}, i = {1}, d = {2}", s, i, d);
            Console.ReadLine();
        }
    }
}
$ csc def.cs
$ def.exe
s = 1, i = 10, d = 11

左值與右值

C#中的兩種表達(dá)式

  1. lvalue 左值表達(dá)式可出現(xiàn)在賦值語句的左邊或右邊
    變量是左值的,可出現(xiàn)在賦值語句的右邊格二。
int i = 10;
  1. rvalue 右值表達(dá)式可出現(xiàn)在賦值語句的右邊劈彪,不能出現(xiàn)在賦值語句的左邊。
    數(shù)值是右值的顶猜,因此不能被賦值沧奴,不能出現(xiàn)在賦值語句的左邊。
10 = 100;// 無效語句长窄,編譯時錯誤滔吠。

常量

  • 類是一種活動的數(shù)據(jù)結(jié)構(gòu)
    面向?qū)ο蠓治龊驮O(shè)計產(chǎn)生之前远寸,程序員把程序當(dāng)作指令的序列。焦點主要放在指令的組合和優(yōu)化上屠凶。隨著面向?qū)ο蟮某霈F(xiàn)驰后,焦點從優(yōu)化指令轉(zhuǎn)移到組織程序的數(shù)據(jù)和功能上。程序的數(shù)據(jù)和功能被組織為邏輯上相關(guān)的數(shù)據(jù)項和函數(shù)的封裝集合矗愧,并稱為類灶芝。
    類是一個能存儲數(shù)據(jù)并執(zhí)行代碼的數(shù)據(jù)結(jié)構(gòu),包含數(shù)據(jù)成員和函數(shù)成員唉韭。
撲克牌程序

方法

var關(guān)鍵字并不是特定類型變量的符號夜涕,只是句法上的速記,表示任何可以從初始化語句的右邊推斷出的類型属愤。C#中的var不像JS的那樣可以引用不同類型女器,C#的var是從等號右邊推斷出的實際類型的速記,它并不改變C#的強類型性質(zhì)住诸。

  • var只能用于本地變量驾胆,不能用于字段。
  • var只能在變量聲明中包含初始化時使用
  • 一旦編譯器推斷出變量的類型贱呐,它就是固定且不能更改的丧诺。
using System;
namespace CalculorApp
{
    class NumberManipulator
    {
        // 方法調(diào)用
        public int Max(int i, int j)
        {
            return i>j ? i : j;
        }
        // 遞歸方法調(diào)用
        // 一個方法可以自我調(diào)用,就是所謂的遞歸奄薇。
        public int Factorial(int i)
        {
            if(i==1){
                return 1;
            }else{
                return Factorial(i-1)*i;
            }
        }
        // 按值傳遞參數(shù)
        // 參數(shù)傳遞的默認(rèn)形式驳阎,但調(diào)用方法時會為每個值創(chuàng)建一個新的存儲位置。
        // 實際參數(shù)的值會復(fù)制給形參馁蒂,實參和形參使用的是兩個不同內(nèi)存的值呵晚。
        // 但形參的值發(fā)生改變時,不會影響實參的值沫屡,從而保證實參數(shù)據(jù)的安全饵隙。
        public void Swap(int i, int j)
        {
            int tmp;
            tmp = i;
            i = j;
            j = tmp;
        }
        // 按引用傳遞參數(shù)
        // 引用參數(shù)是一個對變量的內(nèi)存位置的引用。
        // 按引用傳遞參數(shù)時谁鳍,與值參數(shù)不同的時癞季,不會為參數(shù)創(chuàng)建新的存儲位置劫瞳。
        // 引用參數(shù)表示與提供方法的實際參數(shù)具有相同的內(nèi)存位置倘潜。
        // C#中使用ref關(guān)鍵字聲明引用參數(shù)
        public void RefSwap(ref int i, ref int j)
        {
            int tmp;
            tmp = i;
            i = j;
            j = tmp;
        }
        // 按輸出傳遞參數(shù)
        // return 語句可用于只從函數(shù)中返回一個值,使用輸出參數(shù)可從函數(shù)中返回多個值志于。
        // 輸出參數(shù)會把方法輸出的數(shù)據(jù)賦給自己涮因,其他方面與引用參數(shù)相似。
        public void Output(out int i, out int j)
        {
            // 提供給輸出參數(shù)的變量不需要賦值
            // 當(dāng)需要從一個參數(shù)沒有指定初始化的方法中返回值時伺绽,輸出參數(shù)特別有用养泡。
            i = Convert.ToInt32(Console.ReadLine());
            j = Convert.ToInt32(Console.ReadLine());
        }
        // 入口點
        static void Main(string[] args)
        {
            NumberManipulator nm = new NumberManipulator();
            /*
            int i = Convert.ToInt32(Console.ReadLine());
            int j = Convert.ToInt32(Console.ReadLine());
            int max = nm.Max(i, j);
            Console.WriteLine("i = {0}, j = {1}, max = {2}", i, j, max);
            
            int i = Convert.ToInt32(Console.ReadLine());
            int result = nm.Factorial(i);
            Console.WriteLine("i = {0}, result = {1}", i, result);
            
            int i = Convert.ToInt32(Console.ReadLine());
            int j = Convert.ToInt32(Console.ReadLine());
            nm.Swap(i,j);
            Console.WriteLine("i = {0}, j = {1}", i, j);
            
            int i = Convert.ToInt32(Console.ReadLine());
            int j = Convert.ToInt32(Console.ReadLine());
            nm.RefSwap(ref i, ref j);
            Console.WriteLine("i = {0}, j = {1}", i, j);
            
            int i,j;
            nm.Output(out i, out j);
            Console.WriteLine("i = {0}, j={1}", i, j);
            */
        }
    }
}

數(shù)組

using System;
namespace ArrayApp
{
    class Ary
    {
        static void Main(string[] args)
        {
            // 數(shù)組
            // 數(shù)組是一個存儲相同類型元素的固定大小的順序集合
            // 數(shù)組是用來存儲數(shù)據(jù)的集合嗜湃,數(shù)組是相同類型變量的集合。
            // 數(shù)組中指定元素是通過索引來訪問的澜掩,數(shù)組是由連續(xù)的內(nèi)存位置組成的购披。
            // 最低的位置對應(yīng)第一個元素,最高的地址對應(yīng)最后一個元素肩榕。
            
            // 聲明數(shù)組
            // 聲明數(shù)組不會在內(nèi)存中初始化數(shù)組
            int[] arr;
            
            // 初始化數(shù)組
            // 當(dāng)初始化數(shù)組變量時刚陡,可賦值給數(shù)組。
            // 數(shù)組是引用類型株汉,需使用new來創(chuàng)建數(shù)組的實例筐乳。
            arr = new int[10];
            
            // 賦值給數(shù)組
            // 通過使用索引賦值給一個單獨的數(shù)組元素
            arr[0] = 1;
            // 可以在聲明數(shù)組的同時給數(shù)組賦值
            double[] darr = {1.1, 2.2, 3.3};
            // 可以創(chuàng)建并初始化一個數(shù)組
            int[] iarr = new int[3]{1,2,3};
            // 創(chuàng)建并初始化數(shù)組時可以省略數(shù)組的大小
            int[] iary = new int[]{3,2,1};
            // 可賦值數(shù)組變量到另一個目標(biāo)數(shù)組變量中
            // 此時目標(biāo)和源會指向相同的內(nèi)存位置
            int[] src = new int[]{10,20,30};
            int[] dst = src;
            // 創(chuàng)建數(shù)組時,C#編譯器會根據(jù)數(shù)組類型乔妈,隱式初始化每個數(shù)組元素為一個默認(rèn)值蝙云。
            // int數(shù)組的所有元素都會被初始化為0
            
            // 訪問數(shù)組元素
            // 元素通過帶索引的數(shù)組名稱來訪問
            int score = dst[1];
            
            // 遍歷數(shù)組
            foreach(int i in dst)
            {
                Console.WriteLine("Element = {0}", i);
            }
            
            for(int j = 0; j < src.Length; j++)
            {
                Console.WriteLine("Item[{0}] = {1}", j, dst[j]);
            }
            
            Console.ReadLine();
            
        }
    }
}

字符串

using System;
namespace StringApp
{
    class Str
    {
        static void Main(string[] args)
        {
            // 字符串
            // C#中可使用字符數(shù)組表示數(shù)組,可使用string關(guān)鍵字聲明字符串變量路召。
            // string關(guān)鍵字是System.String類的別名
            
            // 通過給string變量指定一個字符串
            string firstname, lastname;
            firstname = "Bruce";
            lastname = "Lee";
            // 字符串連接
            string fullname = firstname + lastname;
            Console.WriteLine(fullname);//BruceLee
            
            //通過使用String類構(gòu)造函數(shù)
            char[] letters = {'a', 'n', 't', 'm', 'a', 'n'};
            string nickname = new string(letters);
            Console.WriteLine(nickname);//antman
            
            //通過方法返回字符串
            string[] msgs = {"GNU", "is","Not","UNIX"};
            string message = String.Join(" ", msgs);
            Console.WriteLine(message);//GNU is Not UNIX
            
            //用于轉(zhuǎn)化值得格式化方法
            DateTime dt = new DateTime(2018, 7, 26, 12, 30, 00);
            string datetime = String.Format("{0:d} {0:t}",dt);
            Console.WriteLine(datetime);//2018/7/26 12:30
            
            Console.ReadLine();
        }
    }
}

結(jié)構(gòu)體

using System;

namespace StructApp{
    // 結(jié)構(gòu)體
    // 結(jié)構(gòu)體是值類型的數(shù)據(jù)結(jié)構(gòu)
    // 結(jié)構(gòu)體使得單一變量可存儲各種數(shù)據(jù)類型的數(shù)據(jù)勃刨。
    // 結(jié)構(gòu)體使用struct關(guān)鍵字創(chuàng)建
    // 結(jié)構(gòu)體是用來代表一個記錄
    public struct Kv
    {
        //結(jié)構(gòu)體聲明字段無法賦初值,類可以股淡。
        private string key;
        private string val;
        // 結(jié)構(gòu)體的構(gòu)造函數(shù)中朵你,必須為結(jié)構(gòu)體所有字段賦初值,類的構(gòu)造函數(shù)無此限制揣非。
        public Configs(string _key, string _val)
        {
            this.key = _key;
            this.val = _val;
        }
        public string getKey(){
            return key;
        }
        public string getVal(){
            return val;
        }
    }
    // 結(jié)構(gòu)體是值類型抡医,類是引用類型。
    // 結(jié)構(gòu)體不支持繼承
    // 結(jié)構(gòu)體不能聲明默認(rèn)的構(gòu)造函數(shù)
    public class StructCls
    {
        public static void Main(string[] args)
        {
            Kv app = new Kv("appid","va2lq2en1");
            Kv web = new Kv("website","http://yourname.com");
            
            Console.WriteLine("{0}:{1}", app.getKey(), app.getVal());
            Console.WriteLine("{0}:{1}", web.getKey(), web.getVal());
            
            Console.ReadLine();
            
        }
    }   
}

枚舉

using System;
namespace EnumApp
{
    class EnumCls
    {
        // 枚舉
        // 枚舉是一組命名整型常量早敬,枚舉是值類型忌傻,也就是說,枚舉包含自己的值搞监,不能繼承或傳遞繼承水孩。
        // 枚舉列表中每個符號代表一個整數(shù)值,一個比它前面的符號大的整數(shù)值琐驴。
        // 默認(rèn)情況下俘种,第一個枚舉符號的值為0。
        public enum Week {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
        
        public static void Main(string[] args)
        {
            int sun = (int)Week.Sunday;
            int mon = (int)Week.Monday;
            int tues = (int)Week.Tuesday;
            //Sunday:0, Monday:1, Tuesday:2     
            Console.WriteLine("Sunday:{0}, Monday:{1}, Tuesday:{2}", sun, mon, tues);
            Console.ReadLine();
        }
    }
}

using System;

namespace ClsApp
{
    // 類的定義
    // 類的定義以關(guān)鍵字class開始绝淡,后跟類名宙刘。
    // 類的默認(rèn)訪問標(biāo)識符是internal
    // 類的陳云默認(rèn)訪問標(biāo)識符為private
    internal class Cls{
        // 成員變量
        // 成員變量是對象的屬性,且保持私有來實現(xiàn)封裝牢酵,只能使用公共成員函數(shù)來訪問悬包。
        private double length;
        private double width;
        private double height;
        // 靜態(tài)變量
        // 靜態(tài)變量用于定義常量,其值直接調(diào)用類而無需創(chuàng)建類的實例來獲取馍乙。
        // 靜態(tài)變量在成員函數(shù)或類的定義外部進(jìn)行初始化布近,也可在類的定義內(nèi)部初始化靜態(tài)變量垫释。
        public static double PI;
        //public static double PI = 3.14;//錯誤:類、結(jié)構(gòu)或接口成員聲明中的標(biāo)記“=”無效
        //public static count;//類撑瞧、結(jié)構(gòu)或接口成員聲明中的標(biāo)記“;”無效
        public static int count;//類棵譬、結(jié)構(gòu)或接口成員聲明中的標(biāo)記“;”無效
        
        // 構(gòu)造函數(shù)
        // 類的構(gòu)造函數(shù)是類的特殊成員函數(shù)
        // 當(dāng)創(chuàng)建類的新對象時自動執(zhí)行
        // 構(gòu)造函數(shù)的名稱與類名完全相同,且無返回值预伺。
        // 默認(rèn)構(gòu)造函數(shù)無參數(shù)茫船,有參數(shù)的構(gòu)造函數(shù)稱為參數(shù)化構(gòu)造函數(shù)。
        // 參數(shù)化構(gòu)造函數(shù)在創(chuàng)建對象時給對象賦初始值
        // public void Cls(){} //錯誤成員名稱不能與它們的封閉類型相同
        Cls(double _length = 0.0, double _width = 0.0, double _height = 0.0)
        {
            Console.WriteLine("對象已創(chuàng)建");
            length = _length;
            width = _width;
            height = _height;
        }
        // 析構(gòu)函數(shù)
        // 析構(gòu)函數(shù)是類的特殊成員函數(shù)
        // 當(dāng)類的對象超出范圍時執(zhí)行
        // 析構(gòu)函數(shù)名稱是在類名前加上波浪號~作為前綴
        // 析構(gòu)函數(shù)無返回值且無參數(shù)
        // 析構(gòu)函數(shù)用于在結(jié)束程序之前釋放資源
        // 析構(gòu)函數(shù)不能繼承或重載
        ~Cls()
        {
            Console.WriteLine("對象已銷毀");
        }
        // 成員函數(shù)
        // 類的成員函數(shù)是在類定義中有它的定義或原型的函數(shù)
        // 作為類的成員扭屁,能在類的任何對象上操作算谈,且能訪問該對象的類的所有成員。
        public void SetLength(double _length = 0.0)
        {
            length = _length;
        }
        public double GetLength(){
            return length;
        }
        
        public double GetVolume()
        {
            return length * width * height;
        }
        // 靜態(tài)變量可在成員或類的外部進(jìn)行初始化料滥,也可在類的定義內(nèi)部初始化然眼。
        public void SetCount()
        {
            count++;
        }
        public int GetCount()
        {
            return count;
        }
        // 靜態(tài)函數(shù)
        // 靜態(tài)函數(shù)只能訪問靜態(tài)變量
        // 靜態(tài)函數(shù)在對象被創(chuàng)建之前就已經(jīng)存在
        // 靜態(tài)函數(shù)無需實例化即可調(diào)用
        public static double GetArea(double radius = 0.0)
        {
            return PI * radius;
        }
        // 入口點
        private static void Main(string[] args)
        {
            Cls cls = new Cls(1.0, 2.0, 3.0);
            double result = cls.GetVolume();
            Console.WriteLine("volumn = {0}", result);
            
            /*
            double input = Convert.ToDouble(Console.ReadLine());
            
            Cls.PI = 3.14;
            double area = Cls.GetArea(input);
            Console.WriteLine("area = {0}", area);
            Console.ReadLine();
            */
        }
    }
}

繼承

using System;

namespace InheritanceApp
{
    // 基類
    // 一個類可派生自多個類或接口,意味著類可從多個基類或接口繼承數(shù)據(jù)和函數(shù)葵腹。
    class Shape
    {
        protected double width;
        protected double height;
        public Shape(double _width, double _height)
        {
            width = _width;
            height = _height;
        }
        public void SetWidth(double _width)
        {
            width = _width;
        }
        public void SetHeight(double _height)
        {
            height = _height;
        }
    }
    // 派生類
    class Rectangle:Shape
    {
        private double area;
        // 基類初始化
        // 派生類繼承了基類的成員變量和函數(shù)高每,父類對象應(yīng)在子類對象創(chuàng)建前被創(chuàng)建,可在成員初始化列表中進(jìn)行父類的初始化践宴。
        public Rectangle(double _width, double _height):base(_width, _height)
        {
            area = width * height;
        }
        public double GetArea()
        {
            return area;
        }
        public double GetCost(double _price){
            return area * _price;
        }
    }
    class Test
    {
        static void Main(string[] args)
        {
            Rectangle rect = new Rectangle(10.0, 20.0);
            Console.WriteLine("area = {0}, cost = {1}", rect.GetArea(), rect.GetCost(5.5));
            Console.ReadLine();
        }
    }
}

多態(tài)


using System;

namespace App
{
    class Print
    {
        // 函數(shù)重載
        static void Out(int i)
        {
            Console.WriteLine("{0}",Convert.ToInt32(i));
            Console.ReadLine();
        }
        static void Out(double d)
        {
            Console.WriteLine("{0}",Convert.ToDouble(d));
            Console.ReadLine();
        }
        static void Out(string s)
        {
            Console.WriteLine("{0}",Convert.ToString(s));
            Console.ReadLine();
        }
        static void Main(string[] args)
        {
            Print.Out(1);
            Print.Out(1.1);
            Print.Out("hello");
        }
    }
}

獲取系統(tǒng)相關(guān)信息

using System;
using System.Collections.Generic;
namespace App
{
    public class OS
    {       
        public static Dictionary<string, string> GetOS()
        {
            
            int major = System.Environment.OSVersion.Version.Major;
            int minor = System.Environment.OSVersion.Version.Minor;
            string[] arr = {Convert.ToString(major), Convert.ToString(minor)};
            
            string osVersion = string.Join(".", arr);
            string osName = "";
            switch(osVersion){
                case "5.0":
                    osName = "Windows2000"; 
                    break;
                case "5.1":
                    osName = "WindowsXP"; 
                    break;
                case "5.2": 
                    osName = "Windows2003";
                    break;
                case "6.0":
                    osName = "Windows2008";
                    break;
                case "6.1": 
                    osName = "Windows7"; 
                    break;
                case "6.2": 
                    osName = "Windows8"; 
                    break;
                case "10.0": 
                    osName = "Windows10"; 
                    break;
                default:
                    osName = "Unknown";
                    break;
            }
            
            Dictionary<string, string> dict = new Dictionary<string, string>();
            dict.Add("OSVersion", osVersion);
            dict.Add("OSName", osName);
            return dict;
        }
        public static Dictionary<string, string> GetIp()
        {
            string hostname = System.Net.Dns.GetHostName();
            
            System.Net.IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(hostname);
            string ip = ipEntry.AddressList[1].ToString();
            
            Dictionary<string,string> dict = new Dictionary<string, string>();
            dict.Add("HostName", hostname);
            dict.Add("IP", ip);
            
            return dict;
        }
        static void Main(string[] args)
        {
            foreach(KeyValuePair<string, string> kvp in OS.GetIp())
            {
                Console.WriteLine("{0}:{1}",kvp.Key, kvp.Value);
            }
            
            //操作系統(tǒng)信息
            OperatingSystem os = System.Environment.OSVersion;
            Console.WriteLine("Platform:{0}, ServicePack:{1}, Version:{2}, VersionString:{3}", os.Platform, os.ServicePack, os.Version, os.VersionString);
            
            Console.WriteLine("CLR Version:{0}", System.Environment.Version);
            
            //檢查程序運行時間
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            timer.Start();
            
            decimal total = 0;
            for(int i=0; i<100000; ++i){
                    total = total + (decimal)Math.Sqrt(i);
            }
            
            timer.Stop();
            Console.WriteLine("ElapsedMilliseconds:{0}, ElapsedTime:{1}", timer.ElapsedMilliseconds, timer.Elapsed);
        }
    }
}

MVC開發(fā)所使用的C#語言特性

使用自動實現(xiàn)的屬性

常規(guī)的C#屬性可以暴露類的數(shù)據(jù)片段鲸匿,這種數(shù)據(jù)片段與設(shè)置和接收數(shù)據(jù)采取了一種松耦合的方式。

// 定義屬性
namespace App.Models{
  public class Product{
    //字段 name 
    private string name;
    //在類中定義屬性 Name阻肩,屬性是帶有g(shù)etter带欢、setter塊的成員
    public string Name{
      get {return name;}//讀取塊
      set{name = value;}//設(shè)置塊
    }
  }
}

// 在控制器中使用屬性
namespace App.Controllers{
  public class HomeController : Controller {
    public ViewResult Index(){
      // 創(chuàng)建新的Product對象
      Product product = new Product();
      // 設(shè)置屬性值
      product.Name = "alice";
      // 讀取屬性
      string productName = product.Name;
      // 生成視圖
      return View("Result", (object)String.Format("product name is {0}", productName));
    }
  }
}

屬性要具有靈活性,沒有重復(fù)的gettersetter烤惊,解決辦法是使用自動實現(xiàn)的屬性乔煞,也稱為“Automatic Property”自動屬性。利用自動屬性柒室,可采用字段支持式屬性模式渡贾,而無需定義該字段或在gettersetter中指定代碼主籍。

//自動實現(xiàn)的屬性
namespace App.Models{
  public class Product{
    // 并未定義getter和setter的體谊惭,也未定義該屬性返回的字段,兩者由C#編譯器在類被編譯時自動完成驶忌。
    public int ProductID {get; set;}
    // 使用自動屬性與使用規(guī)則屬性沒什么不同
    public string Name{get; set;}
    // 使用自動屬性可減少一些輸入擂仍,形成更易于閱讀的代碼囤屹,但仍能保持屬性的靈活性。
    // 若需改變一個屬性的實現(xiàn)方式防楷,還可返回到規(guī)則屬性的格式牺丙。
    public decimal Price{get; set;}
  }
}

將自動屬性切換成規(guī)則屬性

namespace App.Models{
  public class Product{
    //字段
    private string name;
    // 自動屬性
    public int ProductID {get; set;}
    // 規(guī)則屬性:必須同時實現(xiàn)getter和setter,以回到規(guī)則屬性的定義方式复局。
    public string Name {
      // C#在一個屬性中不支持混用自動和規(guī)則風(fēng)格的getter和setter
      get{ return ProductID + name; }
      set{ name = value; }
    }
  }
}

使用對象與集合的初始化器

namespace App.Controllers {
  public class HomeController:Controller{
    public ViewResult CreateProduct(){
      // 創(chuàng)建新的Product對象
      Product product = new Product();
      // 設(shè)置屬性值
      product.ProductID = 100;
      product.Name = "alice";

      return View("Result", (object)String.Format("product name is {0}", product.Name));
    }
  }
}

使用對象初始化器(Object Initializer)能夠在一個步驟中創(chuàng)建并填寫實例

// 創(chuàng)建并填充對象
Product product = new Product(){
  ProductID = 100,
  Name = "alice"
}

類名后調(diào)用的花括號形成了初始化器冲簿,目的是為參數(shù)提供值,以此作為該對象的構(gòu)造過程亿昏。已同樣的特性作為構(gòu)造過程峦剔,也能對集合和數(shù)組的內(nèi)容進(jìn)行初始化。

// 構(gòu)建并初始化一個數(shù)組
string[] strArr = {"Windows", "Linux", "UNIX"}

//構(gòu)建并初始化發(fā)反省集合庫的類
List<init> intList = new List<int> {10, 20, 30};

Dictionary<string, int> dic = new Dictionanry<string, int>{
  {"windows", 10},
  {"Linux", 20},
  {"UNIX", 30}
};

使用擴展方法

擴展方法(Extension Method)指那些不是你擁有的角钩、不能直接修改的類添加方法的一種方便的方式吝沫。

namespace App.Models{
  public class ShoppingCart {
    // 類中封裝了一個Product對象的列表
    public List<Product> Products {get; set;}
  }
}

定義擴展方法

namespace App.Models{
  public static class ExtensionMethods{
    // this關(guān)鍵字把TotalPrices標(biāo)記為一個擴展方法
    public static decimal TotalPrices(this ShoppingCart cart){
      decimal total = 0;
      foreach(Product product  in cart.Products){
        total += product.Price;
      }
      return total;
    }
  }
}

使用擴展方法

namespace App.Controllers{
  public class HomeController{
    public ViewResult UseExtension(){
      // 創(chuàng)建并填充
      ShoppingCart cart = new ShoppingCart{
        Products = new List<Product>{
          new Product {Name = "kayak", Price = 10},
          new Product{Name = "ball", Price = 20}
        }
      };
      // 計算購物車總價
      decimal total = cart.TotalPrices();

      return View("Result", (object)String.Format("total is {0:c}", total));
    }
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市递礼,隨后出現(xiàn)的幾起案子惨险,更是在濱河造成了極大的恐慌,老刑警劉巖脊髓,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辫愉,死亡現(xiàn)場離奇詭異,居然都是意外死亡将硝,警方通過查閱死者的電腦和手機恭朗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來依疼,“玉大人痰腮,你說我怎么就攤上這事÷砂眨” “怎么了膀值?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長误辑。 經(jīng)常有香客問我虫腋,道長,這世上最難降的妖魔是什么稀余? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任悦冀,我火速辦了婚禮,結(jié)果婚禮上睛琳,老公的妹妹穿的比我還像新娘盒蟆。我一直安慰自己,他們只是感情好师骗,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布历等。 她就那樣靜靜地躺著,像睡著了一般辟癌。 火紅的嫁衣襯著肌膚如雪寒屯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音寡夹,去河邊找鬼处面。 笑死,一個胖子當(dāng)著我的面吹牛菩掏,可吹牛的內(nèi)容都是我干的魂角。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼智绸,長吁一口氣:“原來是場噩夢啊……” “哼野揪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瞧栗,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤斯稳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后迹恐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挣惰,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年系草,在試婚紗的時候發(fā)現(xiàn)自己被綠了通熄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡找都,死狀恐怖唇辨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情能耻,我是刑警寧澤赏枚,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站晓猛,受9級特大地震影響饿幅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜戒职,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一栗恩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧洪燥,春花似錦磕秤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至再来,卻和暖如春蒙兰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工搜变, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留采缚,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓痹雅,卻偏偏與公主長得像仰担,于是被迫代替她去往敵國和親糊识。 傳聞我的和親對象是個殘疾皇子绩社,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,150評論 0 13
  • 版權(quán)聲明:本文為 gfson 原創(chuàng)文章赂苗,轉(zhuǎn)載請注明出處愉耙。注:作者水平有限,文中如有不恰當(dāng)之處拌滋,請予以指正朴沿,萬分感謝...
    gfson閱讀 2,998評論 0 6
  • 親愛的讀者們: 歡迎大家繼續(xù)閱讀并支持我的作品,近日將繼續(xù)更新败砂。最后祝大家暑假快樂赌渣! 在夢想之間 5/31 日 中國
    在夢想之間閱讀 109評論 0 0
  • 英國某小鎮(zhèn)坚芜。 有一個青年人,整日以沿街為小鎮(zhèn)的人說唱為生斜姥;有一個華人婦女鸿竖,遠(yuǎn)離家人,在這兒打工铸敏。他們總是在同一個小...
    窗爸爸家居閱讀 108評論 0 0
  • 我想寫一首詩缚忧, 但是, 我不曾見過大海杈笔, 也不曾去過草原闪水, 現(xiàn)在沒有太陽暖暖地照著, 也沒有月光透過枝丫斜斜灑下蒙具,...
    非久閱讀 278評論 0 1