類庫探源——System.ValueType

1、MSDN描述git

ValueType 類:提供值類型的基類瀏覽器

命名空間: Systemui

程序集:   mscorlib.dllspa

繼承關係:線程

 

值類型包括:字符、整數、浮點、布爾、枚舉、結構(其實字符、整數、浮點、布爾是結構,下面會說明)3d

 

2、值類型花名冊指針

1. 字符code

Char 結構: 表示一個 Unicode 字符。orm

命名空間:   System對象

程序集   : mscorlib.dll

原型定義:

[SerializableAttribute]
[ComVisibleAttribute(true)]
public struct Char : IComparable, IConvertible, IComparable<char>, IEquatable<char>

在C# 中 char 是 System.Char 的別名

System.Char 繼承 System.ValueType

using System;

class App
{
    static void Main()
    {
        var charType1 = typeof(Char);
        var charType2 = typeof(char);    // char 是 Char 在C#中的別名
        
        Console.WriteLine(charType1);
        Console.WriteLine(charType1.BaseType);        
        Console.WriteLine(charType2);
    }
}

經常使用屬性和方法:

IsDigit(Char)           是不是數字

IsLetter(Char)          是不是字母

IsLetterOrDigit(Char)   是不是數字或字母

 

2. 整數

分爲有符號整數和無符號整數

有符號整數

SByte <--> sbyte      8位

Int16 <--> short       16位

Int32 <--> int          32位

Int64 <--> long        64位

無符號

Byte  <--> byte

UInt16 <--> ushort

UInt32 <--> uint

UInt64 <--> ulong

 

3. 浮點

單精度

Single  <--> float

雙精度

Double <--> double

 

4. 布爾

Boolean  <--> bool

 

5. 枚舉

Enum 類:爲枚舉提供基類

命名空間:   System

程序集 :   mscorlib.dll

原型定義:

[SerializableAttribute]
[ComVisibleAttribute(true)]
public abstract class Enum : ValueType, IComparable, IFormattable, IConvertible

能夠看出 Enum 是class

在C# 中 System.Enum 的別名爲 enum

 

常見屬性和方法:

Parse(Type, String)        解析枚舉值

TryParse<TEnum>(String, TEnum) 

 

6. 一些常見的結構 struct

1. Char、Int1六、Int3二、Int6四、Single 、Double 以及無符號版本

 

2. IntPtr 結構:用於表示指針或句柄的平臺特定類型

經常使用構造器:

IntPtr(Int32)

IntPtr(Int64)

var intPtr1 = new  IntPtr(23222);
var intPtrZero = IntPtr.Zero; // 表明已初始化爲零的指針或句柄

 

3. Guid 結構: 表示全局惟一標識符 (GUID)

經常使用構造器:

Guid(String)

 

經常使用屬性和方法:

Guid.Empty        Guid 類的只讀實例,其值保證均爲零

Guid.NewGuid()  產生一個新Guid

Guid.Parse

Guid.TryParse

ToString

 

4. DateTime結構 : 表示時間上的一刻,一般以日期和當天的時間表示

System.DateTime 實例所表示的日期範圍是在這兩個日期之間:0001年1月1日午夜(一天開始之時)和9999年12月31日午夜

 

經常使用構造器

DateTime(int year,int month,int day)

DateTime(int year,int month,int day,int hour,int minute,int second)

 

經常使用靜態屬性

static DateTime Now {get;}

static DateTime Today{get;}     // 返回日期實例,時間部分設爲零

static DateTime UtcNow{get;}

 

經常使用實例屬性

DateTime Date{get;}             // 返回日期,時間部分設爲0

DayOfWeek DoyWeek{get:}         // 返回 System.DayOfWeek 枚舉值

int DayOfYear{get;}            

int Year{get:}

int Month{get:}

int Day{get;}                 

int Hour{get;}                 

int Minute{get:}            

   

日期運算

AddYears(int year)  // year 可爲負 下面month day 之類相似

AddMonths(int month)

AddDays(int day)

AddHours(int hour)

AddMinutes(int minute)

AddSeconds(int second)

 

ToString 格式

經常使用格式 yyyy-MM-dd HH:mm:ss 其餘格式參考MSDN

 

Parse方法與TryParse方法

 代碼以下  demo.cs

using System;

class App
{
    static void Main()
    {      
        // 屬性
        Console.WriteLine("當前時間是 {0}",DateTime.Now);
        Console.WriteLine("當前是 {0}",DateTime.Today);
        DateTime now = DateTime.Now;
        Console.WriteLine("Date {0}",now.Date);
        Console.WriteLine("Year {0}",now.Year);
        Console.WriteLine("Month {0}",now.Month);
        Console.WriteLine("Day {0}",now.Day);
        Console.WriteLine("Hour {0}",now.Hour);
        Console.WriteLine("Minute {0}",now.Minute);
        Console.WriteLine("Second {0}",now.Second);        
        Console.WriteLine("Day of Year {0}",now.DayOfYear);   
        Console.WriteLine("Day of Week {0}",now.DayOfWeek);  
        
        // 運算操做
        now = now.AddHours(2);
        // AddYears AddMonths AddDays AddMinutes AddSeconds
        Console.WriteLine("Date {0}",now.ToString("yyyy-MM-dd HH:mm:ss"));
        
        // Parse
        DateTime dt1 = DateTime.Parse("2016-7-1 9:00");
        Console.WriteLine("Date {0}",dt1.ToString("yyyy-MM-dd HH:mm:ss"));
        
        // TryParse
        DateTime dt2 = DateTime.Now;
        DateTime.TryParse("2016-7-1 9:30",out dt2);
        Console.WriteLine("Date {0}",dt2.ToString("yyyy-MM-dd HH:mm:ss"));
    }
}

編譯 csc demo.cs

運行

 

 

5. TimeSpan結構:表示一個時間間隔

 

6. Nullable<T> 結構:表示基礎類型爲值類型的對象,值類型與引用類型同樣也能夠分配 null

 

==2014-12-22 編輯==

新增一副 System 命名空間下的繼承關係圖

(這幅圖有個很差的地方,簡單類型的也是 Struct 類型,這圖沒畫出來)

 

==2015-1-3 編輯==

一、新增枚舉類型的基本操做

二、類型轉換

三、運行時候值類型與引用類型的內存分佈

四、值類型的裝箱(boxed)和拆箱(unboxed)


 

枚舉類型基本操做

using System;

class App
{
    static void Main()
    {
        var e1 = (Person)1;    // 值強轉枚舉類型        
        Console.WriteLine("The Type of Person: {0}",typeof(Person));    // 原始枚舉類型
        Console.WriteLine("Type :{0}\nItem :{1}\nValue:{2}",e1.GetType(),e1,(int)e1);        
        Console.WriteLine();
        var e2 = (Person)Enum.Parse(typeof(Person),"劉備");    // 從枚舉項到枚舉類型
        Console.WriteLine("Type :{0}\nItem :{1}\nValue:{2}",e2.GetType(),e2,(int)e2);        
    }
    
    enum Person
    {
        劉備=0,
        關羽=1,
        張飛=2
    }
}

效果:

 

 

類型轉換

一、隱式轉換(值類型、引用類型)

值類型:如整型 --> 浮點
引用類型: 子類替換父類

 

二、顯式強轉(值類型和引用類型都可)
(Type)Instance

 

三、as 和 is

as 僅用於引用類型以及可空類型,返回轉換後的實例,如轉換失敗返回 null
對於可空類型 var instance = 1 as int?;
is 判斷兩個類型是否兼容(就是本類型,以及子類是父類等狀況)

 

運行時候值類型與引用類型的內存分佈

在程序運行的時候,值類型內存分佈執行這段代碼的線程的線程棧上引用類型內存分佈在託管堆上

看一個 《CLR Via C# 》的例子

class App
{
    static void Main()
    {
        RefType r1 = new  RefType{X = 8};
        ValType v1 = new  ValType{X = 9};
        
        RefType r2 = r1;    // 傳遞的是引入也就是內存指針,以下圖                
        r2.X = 5;    // r1的X也會變爲5
        System.Console.WriteLine(r1.X);
        
        ValType v2 = v1;    // 拷貝的值,佔用線程棧的空間
        v2.X = 5;
        System.Console.WriteLine(v1.X);    // v1 的值不會改變    仍然是9    
    }
}

// 值類型
struct ValType{public int X{get;set;}}

// 引用類型
class RefType{public int X{get;set;}}

 引用類型除了封裝須要的值外,還有兩個地方須要關注(類型對象指針和同步塊索引)這是比引用類型多得地方

 

值類型的裝箱(boxed)和拆箱(unboxed)

上面講了值類型和引用類型在運行時的內存分佈(值類型分佈在線程棧上、引用類型分佈在託管堆上)。

值類型到引用類型的過程叫裝箱(boxed),這個過程是有編譯器作的,它完成了如下工做:首先取出值類型(如上例說的結構ValType)中真正須要的字段和方法(上例中就是 public int X{get;set;}),而後建一個類把這些真正須要的東西塞到這個由編譯器創建的類中,最後返回這個類的類型對象指針,以便你能訪問到這塊託管堆內存。

被裝箱後的值類型類型到本來值類型的過程叫拆箱(unboxed),這個過程也是編譯器完成的,過程和上面的過程大體相反:首先取出引用類型中真正須要的字段和方法,而後在線程棧上創建一個結構把這些真正須要的字段和方法塞到這個結構中,最後返回這個結構的名字,以便你能訪問這個結構。

裝箱和拆箱須要分配內存(這個過程比較耗時),頻繁的裝箱拆箱會下降程序的運行效率。

 

==2015-3-14 編輯==

現實中的值和引用 來之 C# In Depth

      假定你在讀一份很是棒的東西,但願一個朋友也去讀它。爲了不被人投訴支持盜版,進一步假定它是公共領域中的一份文檔。那麼,須要爲朋友提供什麼才能讓他讀到文檔呢?這徹底取決於閱讀的內容。

      先假設你正在讀的是一份真正的報紙。爲了給你朋友一份,須要影印報紙的所有內容並交給他。屆時,他將得到屬於他本身的一份完整的報紙。在這種狀況下,咱們處理的是 值類型 的行爲。全部信息都在你的手上,不須要從其餘任何地方得到。製做了副本直呼,你的這份信息和朋友的那份都是各自獨立的。能夠在本身的報紙上添加一些註解,他的報紙根本不會改變。

      再假設你正在讀的是一個網頁。與前一次相比,這一次,惟一的須要給你朋友的就是網頁的URL。這是 引用類型 行爲,URL代替引用。爲了讀到真正的文檔,必須在瀏覽器中輸入URL,並要求瀏覽器加載網頁。另外一方面,假如網頁由某種緣由發生了變化(如一個維基頁面,你在上面添加了本身的註釋),你和你的朋友再次經過瀏覽器載入頁面時,都會看到這個變化。

 

未完

相關文章
相關標籤/搜索