国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 編程 > 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();
        }
    }
}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
国产精品一区二区婷婷| 亚洲欧美精品日韩欧美| 天天操天天曰| 在线观看精品一区二区三区| 999福利在线视频| 国产高清在线观看| 在线观看视频污| 超碰免费在线播放| 国产精品免费视频一区一| 国产porn在线| 久色视频在线观看| 国产叼嘿网站免费观看不用充会员| 尤物在线精品视频| 成人免费一区二区三区视频网站| 国产人成在线观看| www免费在线观看视频| 国产伦精品一区二区三区高清版禁| 国产精品区一区二| 波多野结衣久久高清免费| 国产精品视频流白浆免费视频| 国产黄色网页| 非洲黑人最猛性xxxx交| 国产高清自拍视频在线观看| 九色在线网站| jizz在线视频| 99reav| 国产视频中文字幕在线观看| 蜜桃av在线免费观看| 在线视频观看亚洲| 国产系列在线观看| 国内自拍视频在线看免费观看| 69精品视频| 国产精品第八页| 国产精品视频一区二区图片| 国产在线www| 99久久99热久久精品免费看| 国产91久久久久| 国产第一页在线| 国产成人亚洲综合小说区 | 日本中文字幕在线看| 日本视频在线观看一区二区三区| 69视频在线观看| 国产第一页在线视频| 国产精品伦理一区二区三区| 国产香蕉视频在线看| 最近中文字幕mv2018在线高清| 国产原创在线播放| 成在线人视频免费视频| 黄色av网站在线免费观看| av在线免费观看网| 小说区乱图片区| 青草视频在线播放| 狠狠操视频网站| 中文字幕在线观看av| 国产午夜精品一区理论片| 国产三级视频在线播放线观看| 国产小视频在线高清播放| 国产a级网站| 欧美日韩在线视频免费观看| 免费在线超碰| 国产亚洲精品午夜高清影院| 国产视频精品久久| 在线一区二区三区精品| 波多野结衣中文字幕久久| 麻豆精品免费视频入口| 天天操天天射天天插| 中文资源在线官网| 成人日韩欧美| 在线播放一区二区精品产| 九九热视频在线| 精品全国在线一区二区| 欧美韩日国产| 在线伊人免费视频| 国产免费专区| 亚洲国产成人综合| 国产区视频在线观看| jizz在线免费观看| 777电影在线观看| 天堂资源最新版在线视频观看免费网| 国产一区二区三区不卡免费观看| 国产xxxxx| 国产乱精品一区二区三区| 99色在线观看| 国产网站免费看| 国产在线www| 久草网在线视频| 天天艹天天操| 亚洲电影视频在线| 91九色在线看| 国产高潮av| 国产精品69一区二区三区| 日本中文字幕在线看| 秋霞av在线| 亚洲xxxxxx| 国产高潮av| 国产精品ⅴa有声小说| 91超碰在线免费| 开心丁香婷婷深爱五月| 在线免费观看黄色av| ·天天天天操| 中文av字幕| 亚洲成人av在线影院| 一区免费观看| 四虎国产精品永久地址998| 精品国产免费第一区二区| 国产高清在线看| 国产va在线| 在线观看免费观看在线91| 136福利第一导航国产在线| 国产一级二级在线| 黄色片视频在线观看| 久久久久久久久亚洲精品| 久久综合精品视频| 国产老肥熟xxxx在线观看| 尤物视频在线看| 国产无遮挡又黄又爽免费软件| 国产高清在线a视频大全| 99久久99热久久精品免费看| eeuss影影院www在线播放| 日本成人在线播放| 国产农村av| 精品三级久久久久久久电影聊斋| 亚洲精品天堂在线观看| 国产在线小视频| 国产一级黄色片免费| 精品视频一二三| 另类高清dbsm日本tvav| 国产视频中文字幕在线观看| 亚洲欧美国产另类首页| 黄色片视频在线观看| 国产黄色大片在线观看| www久久日com| 91亚洲欧美| 五月天天在线| 免费99热在线观看| 在线中文字幕观看| 国产一区久久精品| 日本一二三区视频免费高清| 91xxx在线观看| 在线视频二区| 国产区av在线| 免费黄色网页在线观看| 91涩漫在线观看c| 中文字幕第一页在线| 开心快乐六月丁香婷婷| 在线免费看av| 91中文字幕| 2020国产在线视频| 天天爱天天做色综合| 欧美高清视频| www.大网伊人| 亚洲91av| jizz一区二区三区| 亚洲天堂影院在线观看| 国产精品入口免费麻豆| 国产乱子伦三级在线播放| 美女av在线播放| 黄网在线免费| 成视频年人免费看黄网站| 免费看成年人视频在线观看| 全网国产福利在线播放| 四虎精品成人a在线观看| 亚洲精品视频区| www在线视频| 免费a在线看| 国产在线观看网站| 91超碰在线免费| 国产精品人人| 在线伊人免费视频| 永久免费在线观看| 天天操夜夜添| 国产女人伦码一区二区三区不卡| 九九热视频免费在线观看| 国产免费专区| 国产网站在线播放| 69国产精品| 欧美日韩在线视频免费观看| 狠狠操天天操夜夜操| 国产网站在线免费观看| 国产精品福利视频一区二区三区| 国产福利免费观看| 亚洲高清在线免费| 黄色免费av| 国产va在线观看| 不卡av免费观看| 超碰在线97国产| 国产野外战在线播放| 亚洲精品在线播放视频| 久草在线视频网| 精品麻豆国产| 国产九色视频| 亚洲精品在线播放视频| 国产毛片在线| 在线视频婷婷| 中文字幕第一页av| 免费中文字幕| 一区二区三区免费视频网站| 国产小视频免费在线网址| www.av在线视频| 精品卡1卡2卡三卡免费网站|