欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C# 值類型的實現(xiàn)

 更新時間:2025年01月22日 09:51:07   作者:詩和遠(yuǎn)方y(tǒng)a  
本文主要介紹了C# 值類型的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1、c#類型

類型(Type)又叫數(shù)據(jù)類型(Data Type)。
A data type is a homogeneous collection of values,effectively prensented,equipped with a set of operations which manipulate these values.

  • 數(shù)據(jù)類型是由相同類型的值組成的集合。比如int[]是整數(shù)的集合。
  • 數(shù)據(jù)類型配備有專門針對自己的值的一組運(yùn)算操作,比如int類型的數(shù)據(jù)可以進(jìn)行加法、減法、乘法、除法操作。深層的意思是,這一組操作是專門為這一種數(shù)據(jù)類型準(zhǔn)備的,我們不能拿數(shù)據(jù)類型A的操作去對數(shù)據(jù)類型B進(jìn)行操作。
  • 數(shù)據(jù)類型的“類型”二字包含有“型號”的意思,也就是說,一個數(shù)據(jù)類型代表著這種數(shù)據(jù)類型的值在內(nèi)存中存儲時需要占多少的內(nèi)存,比如對于int來說,它可存儲-2,147,483,648 到 2,147,483,647范圍內(nèi)的值,需要占4個字節(jié)。我們在存儲數(shù)據(jù)時,應(yīng)該選擇合適的數(shù)據(jù)類型,比如我們想要存儲100這個數(shù)據(jù),如果使用int的話顯得太浪費了,使用byte就夠用了,byte只占一個字節(jié);而如果我們想要存儲256這個數(shù)據(jù),使用byte就不行了,因為byte只能存儲0~255的整數(shù)。所以說,大內(nèi)存存儲小尺寸的數(shù)據(jù)會導(dǎo)致浪費,小內(nèi)存存儲大尺寸的數(shù)據(jù)會導(dǎo)致丟失精度。舉一個現(xiàn)實中的例子,有一個盒子,如果我們拿一個橡皮丟進(jìn)去,空間完全足夠而且還有很多空出來的空間沒有得到利用,而如果我們拿一把椅子丟進(jìn)去就不行了,這時候如果想強(qiáng)制丟進(jìn)去,只能把椅子的一部分放進(jìn)去,椅子就會被損壞了。
  • 數(shù)據(jù)類型會被有效地表示,包括存儲在內(nèi)存中的位置、占內(nèi)存的大小、類型包含的成員(方法、字段、事件等)、類型所繼承的基類型。
  • c#是一種強(qiáng)類型的語言,這意味著每個變量和常量都必須有一個明確的數(shù)據(jù)類型。這樣編譯器就能保證代碼中執(zhí)行的所有運(yùn)算都是類型安全的。例如,如果定義了一個 int 類型的變量,則編譯器允許在加法和減法運(yùn)算中使用此變量, 如果嘗試在一個 string 類型的變量上執(zhí)行相同的運(yùn)算,則編譯器會產(chǎn)生錯誤。
// c#代碼
int a = 10;
string str = "Hello, world!";
int b = a + str;

//輸出結(jié)果為:
//無法將類型“string”隱式轉(zhuǎn)換為“int”
# python代碼
a = 10
a = "Hello, world!"

c#類型分為值類型和引用類型,值類型有結(jié)構(gòu)體和枚舉,引用類型有類、接口、委托。

在這里插入圖片描述

struct MyStruct  // 定義結(jié)構(gòu)體
{

}

Type type = typeof(int); //使用typeof關(guān)鍵字獲取int的類型
Console.WriteLine(type.BaseType); //打印int的基類型
Console.WriteLine(type.BaseType.BaseType); //打印int的基類型的基類型

Console.WriteLine("---------");
type = typeof(MyStruct); //使用typeof關(guān)鍵字獲取MyStruct的類型
Console.WriteLine(type.BaseType); //打印MyStruct的基類型
Console.WriteLine(type.BaseType.BaseType); //打印MyStruct的基類型的基類型

//輸出結(jié)果為:
//System.ValueType
//System.Object
//---------
//System.ValueType
//System.Object

2、值類型

值類型的變量存儲數(shù)據(jù),而引用類型的變量存儲對實際數(shù)據(jù)的引用。

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

結(jié)構(gòu)體和類很相似,結(jié)構(gòu)體通常用來封裝小型相關(guān)變量組。
與類相比,結(jié)構(gòu)體有一些限制,例如它不能聲明為抽象的或密封的,它也不能聲明默認(rèn)構(gòu)造函數(shù)(沒有參數(shù)的構(gòu)造函數(shù))和析構(gòu)函數(shù)。結(jié)構(gòu)體通常用于小型、不可變的數(shù)據(jù)結(jié)構(gòu),而類更適合用于需要更復(fù)雜行為的對象。
結(jié)構(gòu)體在C#中是實現(xiàn)輕量級數(shù)據(jù)結(jié)構(gòu)的強(qiáng)大工具,它在性能上通常優(yōu)于類,因為它避免了垃圾回收的開銷。然而,它也有一定的限制,比如不能被聲明為可空的,并且當(dāng)結(jié)構(gòu)體包含引用類型字段時,可能會引入垃圾回收的開銷。
結(jié)構(gòu)體可以包含構(gòu)造函數(shù)、 常量、 字段、 方法、 屬性、 索引器、 運(yùn)算符、 事件和嵌套類型,但如果同時需要上述幾種成員,則應(yīng)當(dāng)考慮改為使用類作為類型。

struct Student
{
	public int age;
	public int height;
	public double weight;
	public string name;
}

我們不能在結(jié)構(gòu)體中初始化實例字段,可以在結(jié)構(gòu)體中初始化靜態(tài)字段以及常量。

struct Student 
{
	public static int avgAge = 10;  //可以在結(jié)構(gòu)體中初始化靜態(tài)字段
	public const int height = 100;  //可以在結(jié)構(gòu)體中初始化常量
	public int age;  //不能在結(jié)構(gòu)體中初始化實例字段
}

要想初始化實例字段,有兩種方法:一是使用參數(shù)化構(gòu)造函數(shù),二是在聲明結(jié)構(gòu)后分別訪問成員。

struct Student 
{
	public Student(int x)
	{
		age = x;
	}
	//public static int avgAge = 10;
	public int age;
}

Student stu = new Student(10);  //使用參數(shù)化構(gòu)造函數(shù)初始化實例字段
Console.WriteLine(stu.age);
stu.age = 20;  //聲明結(jié)構(gòu)后訪問實例字段
Console.WriteLine(stu.age);

//輸出結(jié)果為:
//10
//20

與類不同,結(jié)構(gòu)的實例化可以使用new運(yùn)算符,也可以不使用。如果使用的話,會創(chuàng)建該結(jié)構(gòu)的對象,并調(diào)用構(gòu)造函數(shù),構(gòu)造函數(shù)不傳入?yún)?shù)的話,調(diào)用的是默認(rèn)構(gòu)造函數(shù),默認(rèn)構(gòu)造函數(shù)會對結(jié)構(gòu)體的成員進(jìn)行初始化;如果不使用的話,就不會調(diào)用構(gòu)造函數(shù),在初始化所有字段之前,字段將保持未賦值狀態(tài)且對象不可用。

struct Student 
{
	public int age;
	public int height;
}

Student stu1; //不使用new創(chuàng)建對象
Student stu2 = new Student();  //使用new創(chuàng)建對象,并調(diào)用構(gòu)造函數(shù)
struct Student 
{
	public int age;
	public int height;
}

Student stu1; //不使用new創(chuàng)建對象
Console.WriteLine(stu1.age);

//輸出結(jié)果為:
//使用了可能未賦值的字段"age"

所以正確的做法應(yīng)該是:

struct Student 
{
	public int age;
	public int height;
}

Student stu1; 
stu1.age = 10;
stu1.height = 130;
Console.WriteLine(stu1.age);
Console.WriteLine(stu1.height);
struct Student 
{
	public int age;
	public int height;
}

Student stu2 = new Student(); 
Console.WriteLine(stu1.age);
Console.WriteLine(stu1.height);

2.2 枚舉

枚舉類型用enum關(guān)鍵字進(jìn)行聲明,它是一種由一組稱為枚舉數(shù)列表的命名常量組成的獨特類型。
通常情況下,最好是在命名空間內(nèi)直接定義枚舉,以便該命名空間中的所有類都能夠同樣方便地訪問它。 但是,還可以將枚舉嵌套在類或結(jié)構(gòu)中。
默認(rèn)情況下,第一個枚舉數(shù)的值為 0,后面每個枚舉數(shù)的值依次遞增 1。

namespace ConsoleApp1
{
    enum Days { Mon, Tue, Wed, Thu, Fri, Sat, Sun };
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine((int)Days.Mon);
            Console.WriteLine((int)Days.Tue);
            Console.WriteLine((int)Days.Wed);
        }
    }
}

//輸出結(jié)果為:
//0
//1
//2

當(dāng)然,也可以強(qiáng)制元素序列從1開始。

namespace ConsoleApp1
{
    enum Days { Mon=1, Tue, Wed, Thu, Fri, Sat, Sun };
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine((int)Days.Mon);
            Console.WriteLine((int)Days.Tue);
            Console.WriteLine((int)Days.Wed);
        }
    }
}

//輸出結(jié)果為:
//1
//2
//3

枚舉類型的默認(rèn)基礎(chǔ)類型是int,所以,上述代碼中定義枚舉類型變量的完整表達(dá)為:

enum Days:int { Mon=1, Tue, Wed, Thu, Fri, Sat, Sun };

枚舉類型變量可賦以基礎(chǔ)類型范圍內(nèi)的任何值,準(zhǔn)許使用的枚舉類型有 byte、 sbyte、 short、 ushort、 int、 uint、 long 或 ulong。

namespace ConsoleApp1
{
    enum Days:byte { Mon=1, Tue=2, Wed=10, Thu=20, Fri=30, Sat=100, Sun=255 };
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine((byte)Days.Mon);
            Console.WriteLine((byte)Days.Tue);
            Console.WriteLine((byte)Days.Wed);
            Console.WriteLine((byte)Days.Thu);
            Console.WriteLine((byte)Days.Fri);
            Console.WriteLine((byte)Days.Sat);
            Console.WriteLine((byte)Days.Sun);
        }
    }
}

//輸出結(jié)果為:
//1
//2
//10
//20
//30
//100
//255

在switch語句中使用枚舉值。

namespace ConsoleApp1
{
    enum Days { Mon, Tue, Wed, Thu, Fri, Sat, Sun };
    class Program
    {
        static void Main(string[] args)
        {
            Days day = (Days)1;
            switch (day)
            {
                case Days.Mon:
                    Console.WriteLine("Today is Mon");
                    break;
                case Days.Tue:
                    Console.WriteLine("Today is Tue");
                    break;
                case Days.Wed:
                    Console.WriteLine("Today is Wed");
                    break;
                case Days.Thu:
                    Console.WriteLine("Today is Thu");
                    break;
                case Days.Fri:
                    Console.WriteLine("Today is Fri");
                    break;
                case Days.Sat:
                    Console.WriteLine("Today is Sat");
                    break;
                case Days.Sun:
                    Console.WriteLine("Today is Sun");
                    break;
            }
        }
    }
}

使用枚舉類型的好處:

  • 明確變量可以存儲的值。
enum Days:byte { Mon=1, Tue=2, Wed=10, Thu=20, Fri=30, Sat=100, Sun=255 };
Days day = Days.Mon;

在這個程序中,一個星期只能包含從星期一到星期日的7天,所以只能取枚舉中的值。

我們可以使用擴(kuò)展方法為枚舉類型添加功能。

namespace ConsoleApp1
{
    // 在非泛型靜態(tài)類中定義擴(kuò)展方法
    public static class Extensions
    {        
        public static Grades minPassing = Grades.D;
        // this關(guān)鍵字在方法定義中用于指定這是一個擴(kuò)展方法
        //this關(guān)鍵字后面跟著的是類型參數(shù),表示這個擴(kuò)展方法可以被任何Grade類型的實例調(diào)用
        public static bool Passing(this Grades grade)  
        {
            return grade >= minPassing;
        }
    }

    public enum Grades { F = 0, D=1, C=2, B=3, A=4 };
    class Program
    {       
        static void Main(string[] args)
        {
            Grades g1 = Grades.D;
            Grades g2 = Grades.F;
            Console.WriteLine("First {0} a passing grade.", g1.Passing() ? "is" : "is not");
            Console.WriteLine("Second {0} a passing grade.", g2.Passing() ? "is" : "is not");

            Extensions.minPassing = Grades.C;
            Console.WriteLine("\r\nRaising the bar!\r\n");
            Console.WriteLine("First {0} a passing grade.", g1.Passing() ? "is" : "is not");
            Console.WriteLine("Second {0} a passing grade.", g2.Passing() ? "is" : "is not");
        }
    }
  }
}

/* 輸出結(jié)果為:
    First is a passing grade.
    Second is not a passing grade.

    Raising the bar!

    First is not a passing grade.
    Second is not a passing grade.
 */

實際上,通過枚舉類型實例對擴(kuò)展方法的調(diào)用,等效于調(diào)用普通非擴(kuò)展方法的方式。也就是說,調(diào)用擴(kuò)展方法與調(diào)用在類型中實際定義的方法之間沒有明顯的差異。

Console.WriteLine("First {0} a passing grade.", g1.Passing() ? "is" : "is not");
Console.WriteLine("Second {0} a passing grade.", g2.Passing() ? "is" : "is not");
// 等效于
Console.WriteLine("First {0} a passing grade.", Extensions.Passing(g1) ? "is" : "is not");
Console.WriteLine("First {0} a passing grade.", Extensions.Passing(g2) ? "is" : "is not");

到此這篇關(guān)于C# 值類型的實現(xiàn)的文章就介紹到這了,更多相關(guān)C# 值類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

最新評論