亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#基礎概念二十五問 16-20

2020-01-24 03:49:39
字體:
來源:轉載
供稿:網友
16.類和結構的區別?

答:
類:

類是引用類型在堆上分配,類的實例進行賦值只是復制了引用,都指向同一段實際對象分配的內存

類有構造和析構函數

類可以繼承和被繼承

結構:

結構是值類型在棧上分配(雖然棧的訪問速度比較堆要快,但棧的資源有限放),結構的賦值將分配產生一個新的對象。

結構沒有構造函數,但可以添加。結構沒有析構函數

結構不可以繼承自另一個結構或被繼承,但和類一樣可以繼承自接口

 

示例:

根據以上比較,我們可以得出一些輕量級的對象最好使用結構,但數據量大或有復雜處理邏輯對象最好使用類。

如:Geoemtry(GIS 里的一個概論,在 OGC 標準里有定義) 最好使用類,而 Geometry 中點的成員最好使用結構

using System;
using System.Collections.Generic;
using System.Text;

namespace Example16
{
    interface IPoint
    {
        double X
        {
            get;
            set;
        }
        double Y
        {
            get;
            set;
        }
        double Z
        {
            get;
            set;
        }
    }
    //結構也可以從接口繼承
    struct Point: IPoint
    {
        private double x, y, z;
        //結構也可以增加構造函數
        public Point(double X, double Y, double Z)
        {
            this.x = X;
            this.y = Y;
            this.z = Z;
        }
        public double X
        {
            get { return x; }
            set { x = value; }
        }
        public double Y
        {
            get { return x; }
            set { x = value; }
        }
        public double Z
        {
            get { return x; }
            set { x = value; }
        }
    }
    //在此簡化了點狀Geometry的設計,實際產品中還包含Project(坐標變換)等復雜操作
    class PointGeometry
    {
        private Point value;

        public PointGeometry(double X, double Y, double Z)
        {
            value = new Point(X, Y, Z);
        }
        public PointGeometry(Point value)
        {
            //結構的賦值將分配新的內存
            this.value = value;
        }
        public double X
        {
            get { return value.X; }
            set { this.value.X = value; }
        }
        public double Y
        {
            get { return value.Y; }
            set { this.value.Y = value; }
        }
        public double Z
       {
            get { return value.Z; }
            set { this.value.Z = value; }
        }
        public static PointGeometry operator +(PointGeometry Left, PointGeometry Rigth)
        {
            return new PointGeometry(Left.X + Rigth.X, Left.Y + Rigth.Y, Left.Z + Rigth.Z);
        }
        public override string ToString()
        {
            return string.Format("X: {0}, Y: {1}, Z: {2}", value.X, value.Y, value.Z);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Point tmpPoint = new Point(1, 2, 3);

            PointGeometry tmpPG1 = new PointGeometry(tmpPoint);
            PointGeometry tmpPG2 = new PointGeometry(tmpPoint);
            tmpPG2.X = 4;
            tmpPG2.Y = 5;
            tmpPG2.Z = 6;

            //由于結構是值類型,tmpPG1 和 tmpPG2 的坐標并不一樣
            Console.WriteLine(tmpPG1);
            Console.WriteLine(tmpPG2);

            //由于類是引用類型,對tmpPG1坐標修改后影響到了tmpPG3
            PointGeometry tmpPG3 = tmpPG1;
            tmpPG1.X = 7;
            tmpPG1.Y = 8;
            tmpPG1.Z = 9;
            Console.WriteLine(tmpPG1);
            Console.WriteLine(tmpPG3);

            Console.ReadLine();
        }
    }
}
結果:
X: 1, Y: 2, Z: 3
X: 4, Y: 5, Z: 6
X: 7, Y: 8, Z: 9
X: 7, Y: 8, Z: 9 


17.接口的多繼承會帶來哪些問題?

答:

C# 中的接口與類不同,可以使用多繼承,即一個子接口可以有多個父接口。但如果兩個父成員具有同名的成員,就產生了二義性(這也正是 C# 中類取消了多繼承的原因之一),這時在實現時最好使用顯式的聲明

示例:

using System;
using System.Collections.Generic;
using System.Text;

namespace Example17
{
    class Program
    {
        //一個完整的接口聲明示例
        interface IExample
        {
            //屬性
            string P
            {
                get;
                set;
            }
            //方法
            string F(int Value);
            //事件
            event EventHandler E;
            //索引指示器
            string this[int Index]
            {
                get;
                set;
            }
        }
        interface IA
        {
            int Count { get; set;}
        }
        interface IB
        {
            int Count();
        }
        //IC接口從IA和IB多重繼承
        interface IC : IA, IB
        {
        }
        class C : IC
        {
            private int count = 100;
            //顯式聲明實現IA接口中的Count屬性
            int IA.Count
            {
                get { return 100; }
                set { count = value; }
            }
            //顯式聲明實現IB接口中的Count方法
            int IB.Count()
            {
                return count * count;
            }
        }
        static void Main(string[] args)
        {
            C tmpObj = new C();

            //調用時也要顯式轉換
            Console.WriteLine("Count property: {0}", ((IA)tmpObj).Count);
            Console.WriteLine("Count function: {0}", ((IB)tmpObj).Count());

            Console.ReadLine();
        }
    }
}
結果:
Count property: 100
Count function: 10000 


18.抽象類和接口的區別?

答:

抽象類(abstract class)可以包含功能定義和實現,接口(interface)只能包含功能定義

抽象類是從一系列相關對象中抽象出來的概念, 因此反映的是事物的內部共性;接口是為了滿足外部調用而定義的一個功能約定, 因此反映的是事物的外部特性

分析對象,提煉內部共性形成抽象類,用以表示對象本質,即“是什么”

為外部提供調用或功能需要擴充時優先使用接口


19.別名指示符是什么?

答:

通過別名指示符我們可以為某個類型起一個別名

主要用于解決兩個命名空間內有同名類型的沖突或避免使用冗余的命名空間

別名指示符在所有命名空間最外層定義,作用域為整個單元文件。如果定義在某個命名空間內,那么它只在直接隸屬的命名空間內起作用

示例:

Class1.cs: 


using System;
using System.Collections.Generic;
using System.Text;

namespace com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01
{
    class Class1
    {
        public override string ToString()
        {
            return "com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01's Class1";
        }
    }
}
Class2.cs: 


using System;
using System.Collections.Generic;
using System.Text;

namespace com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02
{
    class Class1
    {
        public override string ToString()
        {
            return "com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02's Class1";
        }
    }
}
主單元(Program.cs):

using System;
using System.Collections.Generic;
using System.Text;

//使用別名指示符解決同名類型的沖突
//在所有命名空間最外層定義,作用域為整個單元文件
using Lib01Class1 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01.Class1;
using Lib02Class2 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02.Class1;

namespace Example19
{
    namespace Test1
    {
        //Test1Class1在Test1命名空間內定義,作用域僅在Test1之內
        using Test1Class1 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01.Class1;

        class Class1
        {
            //Lib01Class1和Lib02Class2在這可以正常使用
            Lib01Class1 tmpObj1 = new Lib01Class1();
            Lib02Class2 tmpObj2 = new Lib02Class2();
            //TestClass1在這可以正常使用
            Test1Class1 tmpObj3 = new Test1Class1();
        }
    }
    namespace Test2
    {
        using Test1Class2 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01.Class1;

        class Program
        {
            static void Main(string[] args)
            {
                //Lib01Class1和Lib02Class2在這可以正常使用
                Lib01Class1 tmpObj1 = new Lib01Class1();
                Lib02Class2 tmpObj2 = new Lib02Class2();

                //注意這里,TestClass1在這不可以正常使用。
                //因為,在Test2命名空間內不能使用Test1命名空間定義的別名
                //Test1Class1 tmpObj3 = new Test1Class1();

                //TestClass2在這可以正常使用
                Test1Class2 tmpObj3 = new Test1Class2();

                Console.WriteLine(tmpObj1);
                Console.WriteLine(tmpObj2);
                Console.WriteLine(tmpObj3);

                Console.ReadLine();
            }
        }
    }
}

結果:
com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01's Class1
com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02's Class1
com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01's Class1


20.如何手工釋放資源?

答:

 .NET 平臺在內存管理方面提供了GC(Garbage Collection),負責自動釋放托管資源和內存回收的工作。但在以下兩種情況需要我們手工進行資源釋放:一、由于它無法對非托管資源進行釋放,所以我們必須自己提供方法來釋放對象內分配的非托管資源,比如你在對象的實現代碼中使用了一個COM對象;二、你的類在運行是會產生大量實例(象 GIS 中的Geometry),必須自己手工釋放這些資源以提高程序的運行效率

最理想的辦法是通過實現一個接口顯式的提供給客戶調用端手工釋放對象,System 命名空間內有一個 IDisposable 接口,拿來做這事非常合適,省得我們自己再聲明一個接口了 
示例:

using System;
using System.Collections.Generic;
using System.Text;

namespace Example20
{
    class Program
    {
        class Class1 : IDisposable
        {
            //析構函數,編譯后變成 protected void Finalize(),GC會在回收對象前會調用調用該方法
            ~Class1()
            {
                Dispose(false);
            }

            //通過實現該接口,客戶可以顯式地釋放對象,而不需要等待GC來釋放資源,據說那樣會降低效率
            void IDisposable.Dispose()
            {
                Dispose(true);
            }

            //將釋放非托管資源設計成一個虛函數,提供在繼承類中釋放基類的資源的能力
            protected virtual void ReleaseUnmanageResources()
            {
                //Do something...
            }

            //私有函數用以釋放非托管資源
            private void Dispose(bool disposing)
            {
                ReleaseUnmanageResources();

                //為true時表示是客戶顯式調用了釋放函數,需通知GC不要再調用對象的Finalize方法
                //為false時肯定是GC調用了對象的Finalize方法,所以沒有必要再告訴GC你不要調用我的Finalize方法啦
                if (disposing)
                {
                    GC.SuppressFinalize(this);
                }
            } 
        }
        static void Main(string[] args)
        {
            //tmpObj1沒有手工釋放資源,就等著GC來慢慢的釋放它吧
            Class1 tmpObj1 = new Class1();

            //tmpObj2調用了Dispose方法,傳說比等著GC來釋放它效率要調一些
            //個人認為是因為要逐個對象的查看其元數據,以確認是否實現了Dispose方法吧
            //當然最重要的是我們可以自己確定釋放的時間以節省內存,優化程序運行效率
            Class1 tmpObj2 = new Class1();
            ((IDisposable)tmpObj2).Dispose();
        }
    }
}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91牛牛免费视频| 麻豆成人在线看| 国产成人精品视频在线观看| 久久成人精品一区二区三区| 亚洲欧美国内爽妇网| 欧美在线影院在线视频| 97久久超碰福利国产精品…| 亚洲白拍色综合图区| 久久久日本电影| 欧美专区在线观看| 国内外成人免费激情在线视频| 欧美色视频日本高清在线观看| 欧美黑人一级爽快片淫片高清| 日韩在线欧美在线国产在线| 国产精品三级美女白浆呻吟| 亚洲国产精品视频在线观看| 国产经典一区二区| 国语自产精品视频在线看抢先版图片| 精品一区二区三区四区在线| 啪一啪鲁一鲁2019在线视频| 俺去了亚洲欧美日韩| 国产有码一区二区| 中文字幕日韩在线视频| 国产精品欧美一区二区| 国产一区二区三区在线观看网站| 国产亚洲欧洲高清| 国产精品久久久久99| 国产视频精品免费播放| 欧美久久精品午夜青青大伊人| 91九色国产社区在线观看| 日本乱人伦a精品| 亚洲国产精品yw在线观看| 91干在线观看| 2019中文字幕在线| 国产精品久久久久免费a∨大胸| 久久伊人91精品综合网站| 精品亚洲男同gayvideo网站| 亚洲成人中文字幕| 欧美成人精品h版在线观看| 午夜精品福利电影| 国产精品极品在线| 欧美电影第一页| 亚洲黄色www网站| 日韩在线观看免费全| 亚洲成人精品视频| 国产精品视频公开费视频| 美日韩在线视频| 91麻豆国产语对白在线观看| 亚洲欧美色婷婷| 日韩在线免费高清视频| 欧美自拍大量在线观看| 欧美高清在线视频观看不卡| 91免费电影网站| 欧美成人激情图片网| 77777少妇光屁股久久一区| 国产精品久久久精品| 亚洲石原莉奈一区二区在线观看| 日本高清+成人网在线观看| 久久久成人精品| 高清日韩电视剧大全免费播放在线观看| 国产91精品网站| 日本国产高清不卡| 欧美与欧洲交xxxx免费观看| 欧美高清第一页| 欧美最猛性xxxxx免费| 6080yy精品一区二区三区| 成人福利在线观看| 国产一区二区三区网站| 国产欧美日韩中文字幕| 亚洲伊人成综合成人网| 亚洲一区二区三区在线免费观看| 欧美精品性视频| 欧美成人免费观看| 国产精品99久久99久久久二8| 色无极亚洲影院| 中文字幕在线日韩| 欧美国产中文字幕| 国产精品第一第二| 欧美福利视频在线| 日韩国产高清污视频在线观看| 91av在线精品| 亚洲丁香婷深爱综合| 亚洲免费视频在线观看| 日日噜噜噜夜夜爽亚洲精品| 日本成人激情视频| 狠狠久久五月精品中文字幕| 色yeye香蕉凹凸一区二区av| 在线视频免费一区二区| 亚洲精品日韩av| 国产偷亚洲偷欧美偷精品| 精品中文字幕视频| 久久精品国产v日韩v亚洲| 国产日韩综合一区二区性色av| 久色乳综合思思在线视频| 亚洲精品wwwww| 国产日韩av在线播放| 国产在线视频2019最新视频| 97国产成人精品视频| 国产亚洲激情视频在线| 久久视频这里只有精品| 国产精品一区二区久久国产| 在线精品高清中文字幕| 亚洲加勒比久久88色综合| 亚洲伊人第一页| 中文字幕亚洲欧美一区二区三区| 久久久999精品免费| 4p变态网欧美系列| 国产成人一区二区三区| 亚洲三级 欧美三级| 亚洲午夜久久久影院| 亚洲va男人天堂| 91精品国产自产在线老师啪| 欧美精品在线视频观看| 欧美成在线观看| 亚洲视频专区在线| 亚洲2020天天堂在线观看| 久久久久久网址| 日韩视频免费观看| 久久久免费观看| 欧美夜福利tv在线| 中文字幕精品av| 日韩美女av在线免费观看| 国产美女久久精品| 欧美性理论片在线观看片免费| 欧美中文在线观看| 欧美疯狂xxxx大交乱88av| 欧美精品videofree1080p| 日韩大片在线观看视频| 亚洲国产天堂久久综合| 国产精品久久久久不卡| 日韩中文字幕在线看| 久久夜精品va视频免费观看| 亚洲成人精品视频| 亚洲黄色在线观看| 亚洲精品久久久久久久久| 久久久久久香蕉网| 538国产精品一区二区免费视频| 国产精品福利网| 欧美成人一二三| 亚洲精品综合精品自拍| 8x拔播拔播x8国产精品| 国产在线视频2019最新视频| 亚洲精品99久久久久中文字幕| 亚洲加勒比久久88色综合| 在线精品国产成人综合| 国产精品亚洲一区二区三区| 最近2019中文字幕在线高清| 富二代精品短视频| 91精品国产综合久久香蕉922| 国产精品自拍视频| 日韩美女写真福利在线观看| 亚洲精品美女久久久| 亚洲国产精品va| 欧美黑人巨大xxx极品| 国产亚洲精品久久| 国产日韩欧美中文在线播放| 欧美性猛交xxxx免费看漫画| 2020国产精品视频| 色七七影院综合| 亚洲欧美日韩精品久久奇米色影视| 欧美中文在线免费| 97超碰蝌蚪网人人做人人爽| 亚洲美女久久久| 欧美俄罗斯性视频|