欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

C#中的委托解析-創(chuàng)新互聯(lián)

談及到C#的基本特性,“委托”是不得不去了解和深入分析的一個(gè)特性。對(duì)于大多數(shù)剛?cè)腴T的程序員談到“委托”時(shí),都會(huì)想到“將方法作為方法的參數(shù)進(jìn)行傳遞”,很多時(shí)候都只是知道簡單的定義,主要是因?yàn)椤拔小痹诶斫馍嫌休^其他特性比較難的地方。在本次說明中,不會(huì)將委托的簡單聲明和調(diào)用作為重點(diǎn)。

為南漳等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及南漳網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、南漳網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!

  “委托”不需要直接定義一個(gè)要執(zhí)行的行為,而是將這個(gè)行為用某種方法“包含”在一個(gè)對(duì)象中。這個(gè)對(duì)象可以像其他任何對(duì)象那樣使用。在該對(duì)象中,可以執(zhí)行封裝的操作。可以選擇將委托看作之定義了一個(gè)方法的接口,將委托的實(shí)例看作實(shí)現(xiàn)了那個(gè)接口的對(duì)象。

  在“委托”的相關(guān)定義中,我們可以不難看出,“委托與方法“相比較于“接口與類”有著設(shè)計(jì)理念上的相似部分,產(chǎn)生的背景源于”設(shè)計(jì)原則“中的”開放-封閉原則“,”開放-封閉“原則:是說軟件實(shí)體(類,模塊,函數(shù)等等)應(yīng)該可以擴(kuò)展,但是不可修改。換一種說法可能更好的理解”對(duì)于擴(kuò)展是開放的,對(duì)于更改是封閉的“,面對(duì)新的需求,對(duì)于程序的改動(dòng)是通過增加新的代碼進(jìn)行的,而不是更改現(xiàn)有的代碼。

 在C#中委托用delegate關(guān)鍵字定義,使用new操作符構(gòu)造委托實(shí)例,采用傳統(tǒng)的方法調(diào)用語法來回調(diào)函數(shù)(只是要用引用了委托對(duì)象的一個(gè)變量代替方法名)。在C#中,委托在編譯的時(shí)候會(huì)被編譯成類。對(duì)于委托的一個(gè)說明:委托是一個(gè)類,它定義了方法的類型,使得可以將方法當(dāng)作另一個(gè)方法的參數(shù)來進(jìn)行傳遞。委托類既可嵌套在一個(gè)類型中定義,也可以在全局范圍內(nèi)定義。由于委托是類,凡是可以定義類的地方,都可以定義委托。

接下來我們來看一下”委托“的組成,需要滿足的條件:

   1.聲明委托類型。

   2.必須有一個(gè)方法包含了要執(zhí)行的代碼。

   3.必須創(chuàng)建一個(gè)委托實(shí)例。

   4.必須調(diào)用委托實(shí)例。

  接下來大致的了解一下上面所提出的4項(xiàng)條件:

   委托類型實(shí)際上只是參數(shù)類型的一個(gè)列表以及返回類型。規(guī)定了類型的實(shí)例能表示的操作。在調(diào)用一個(gè)委托實(shí)例的時(shí)候,必須保證使用的參數(shù)完全匹配,而且能以指定的方式使用返回值。對(duì)于委托實(shí)例的創(chuàng)建,取決于操作使用實(shí)例方法還是靜態(tài)方法(如果操作是靜態(tài)方法,指定類型名稱就可以,如果是操作實(shí)例方法,需要先創(chuàng)建類型的實(shí)例)。對(duì)于委托的調(diào)用,可以直接調(diào)用委托的實(shí)例的方法就可以完成對(duì)應(yīng)的操作。

  以上談及了”委托“的定義和組成,接下來我們來了解一下如何將方法綁定到”委托“上,以及委托的合并和刪除。

  可以將多個(gè)方法賦給同一個(gè)委托,委托實(shí)例實(shí)際有一個(gè)操作列表與之關(guān)聯(lián)。在System.Delegate類型中提供了兩個(gè)靜態(tài)方法Combine()和Remove()負(fù)責(zé)委托實(shí)例的新增和刪除操作。但是在我們的實(shí)際開發(fā)中,較多的采用-=和+=操作符。

在FCL中,所有的委托類型都派生自MulticastDelegate,該類型在System.MulticastDelegate類型中。

 具體來看一下Combine()方法的底層實(shí)現(xiàn)代碼:

[System.Runtime.InteropServices.ComVisible(true)] 
        public static Delegate Combine(params Delegate[] delegates) 
        {
            if (delegates == null || delegates.Length == 0) 
                return null;

            Delegate d = delegates[0];
            for (int i = 1; i < delegates.Length; i++) 
                d = Combine(d,delegates[i]);
 
            return d; 
        }
public static Delegate Combine(Delegate a, Delegate b) 
        {
            if ((Object)a == null) 
                return b;

            return  a.CombineImpl(b);
        }

以上兩個(gè)方法為System.Delegate類型中,CombineImpl方法在MulticastDelegate重寫。

[System.Security.SecuritySafeCritical]  
        protected override sealed Delegate CombineImpl(Delegate follow)
        { 
            if ((Object)follow == null) 
                return this;
            if (!InternalEqualTypes(this, follow))
                throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTypeMis"));
 
            MulticastDelegate dFollow = (MulticastDelegate)follow;
            Object[] resultList; 
            int followCount = 1; 
            Object[] followList = dFollow._invocationList as Object[];
            if (followList != null) 
                followCount = (int)dFollow._invocationCount;

            int resultCount;
            Object[] invocationList = _invocationList as Object[]; 
            if (invocationList == null)
            { 
                resultCount = 1 + followCount; 
                resultList = new Object[resultCount];
                resultList[0] = this; 
                if (followList == null)
                {
                    resultList[1] = dFollow;
                } 
                else
                { 
                    for (int i = 0; i < followCount; i++) 
                        resultList[1 + i] = followList[i];
                } 
                return NewMulticastDelegate(resultList, resultCount);
            }
            else
            { 
                int invocationCount = (int)_invocationCount;
                resultCount = invocationCount + followCount; 
                resultList = null; 
                if (resultCount <= invocationList.Length)
                { 
                    resultList = invocationList;
                    if (followList == null)
                    {
                        if (!TrySetSlot(resultList, invocationCount, dFollow)) 
                            resultList = null;
                    } 
                    else 
                    {
                        for (int i = 0; i < followCount; i++) 
                        {
                            if (!TrySetSlot(resultList, invocationCount + i, followList[i]))
                            {
                                resultList = null; 
                                break;
                            } 
                        } 
                    }
                } 
                if (resultList == null)
                {
                    int allocCount = invocationList.Length; 
                    while (allocCount < resultCount)
                        allocCount *= 2; 
 
                    resultList = new Object[allocCount];
 
                    for (int i = 0; i < invocationCount; i++)
                        resultList[i] = invocationList[i];

                    if (followList == null) 
                    {
                        resultList[invocationCount] = dFollow; 
                    } 
                    else
                    { 
                        for (int i = 0; i < followCount; i++)
                            resultList[invocationCount + i] = followList[i];
                    }
                } 
                return NewMulticastDelegate(resultList, resultCount, true);
            } 
        }

再來具體看一下Remove()方法的底層實(shí)現(xiàn)代碼,RemoveAll和Remove兩個(gè)方法為System.Delegate類型中,CombineImpl方法在MulticastDelegate重寫。

public static Delegate RemoveAll(Delegate source, Delegate value) 
        {
            Delegate newDelegate = null; 

            do
            {
                newDelegate = source; 
                source = Remove(source, value);
            } 
            while (newDelegate != source); 

            return newDelegate; 
        }
[System.Security.SecuritySafeCritical] 
        public static Delegate Remove(Delegate source, Delegate value)
        {
            if (source == null) 
                return null;
 
            if (value == null) 
                return source;
 
            if (!InternalEqualTypes(source, value))
                throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTypeMis"));

            return source.RemoveImpl(value); 
        }
[System.Security.SecuritySafeCritical] 
        protected override sealed Delegate RemoveImpl(Delegate value)
        {             MulticastDelegate v = value as MulticastDelegate; 

            if (v == null) 
                return this; 
            if (v._invocationList as Object[] == null)
            { 
                Object[] invocationList = _invocationList as Object[];
                if (invocationList == null)
                {
                    if (this.Equals(value))
                        return null; 
                } 
                else
                { 
                    int invocationCount = (int)_invocationCount;
                    for (int i = invocationCount; --i >= 0; )
                    {
                        if (value.Equals(invocationList[i])) 
                        {
                            if (invocationCount == 2) 
                            { 
                                return (Delegate)invocationList[1-i]; 
                            }
                            else
                            {
                                Object[] list = DeleteFromInvocationList(invocationList, invocationCount, i, 1); 
                                return NewMulticastDelegate(list, invocationCount-1, true);
                            } 
                        } 
                    }
                } 
            }
            else
            {
                Object[] invocationList = _invocationList as Object[]; 
                if (invocationList != null) {
                    int invocationCount = (int)_invocationCount; 
                    int vInvocationCount = (int)v._invocationCount; 
                    for (int i = invocationCount - vInvocationCount; i >= 0; i--)
                    { 
                        if (EqualInvocationLists(invocationList, v._invocationList as Object[], i, vInvocationCount))
                        {
                            if (invocationCount - vInvocationCount == 0)
                            { 
                                return null; 
                            } 
                            else if (invocationCount - vInvocationCount == 1)
                            { 
                                return (Delegate)invocationList[i != 0 ? 0 : invocationCount-1];
                            }
                            else 
                            {
                                Object[] list = DeleteFromInvocationList(invocationList, invocationCount, i, vInvocationCount); 
                                return NewMulticastDelegate(list, invocationCount - vInvocationCount, true); 
                            }
                        } 
                    }
                }
            }
 
            return this;
        }

在以上的代碼中,我們了解到了在.NET底層是如何實(shí)現(xiàn)委托實(shí)例的綁定和刪除綁定。

在調(diào)用委托實(shí)例時(shí),所有的操作都是順序執(zhí)行的。如果調(diào)用具有一個(gè)非void的返回類型,則調(diào)用的返回值是最后一個(gè)操作的返回值。如果調(diào)用列表中任何操作拋出異常,都會(huì)阻止執(zhí)行后續(xù)的操作。

 在上面提到了委托列表中出現(xiàn)非void實(shí)例調(diào)用,如果委托實(shí)例中出現(xiàn)多個(gè)非void調(diào)用,并且需要獲取所有的委托實(shí)例的返回值結(jié)果,那么應(yīng)該如何操作,在.NET紅提供了一個(gè)方法GetInvocationList(),用于獲取委托鏈表。

接下來具體了解一下GetInvocationList()的底層代碼:

[System.Security.SecuritySafeCritical] 
        public override sealed Delegate[] GetInvocationList()
        {
            Delegate[] del;
            Object[] invocationList = _invocationList as Object[];
            if (invocationList == null)
            { 
                del = new Delegate[1];
                del[0] = this; 
            } 
            else
            { 
                int invocationCount = (int)_invocationCount;
                del = new Delegate[invocationCount]; 

                for (int i = 0; i < invocationCount; i++) 
                    del[i] = (Delegate)invocationList[i]; 
            }
            return del; 
        }

當(dāng)獲取到委托實(shí)例列表后,可采用循環(huán)迭代的方式,依次獲取每個(gè)委托實(shí)例的返回值。

 再來了解一個(gè)屬性Method,具體看一下此屬性的底層實(shí)現(xiàn)代碼:

public MethodInfo Method 
        {
            get
            {
                return GetMethodImpl(); 
            }
        } 
 
        [System.Security.SecuritySafeCritical] 
        protected virtual MethodInfo GetMethodImpl() 
        {
            if ((_methodBase == null) || !(_methodBase is MethodInfo))
            {
                IRuntimeMethodInfo method = FindMethodHandle(); 
                RuntimeType declaringType = RuntimeMethodHandle.GetDeclaringType(method);
                if (RuntimeTypeHandle.IsGenericTypeDefinition(declaringType) || RuntimeTypeHandle.HasInstantiation(declaringType)) 
                {
                    bool isStatic = (RuntimeMethodHandle.GetAttributes(method) & MethodAttributes.Static) != (MethodAttributes)0; 
                    if (!isStatic)
                    {
                        if (_methodPtrAux == (IntPtr)0)
                        { 
                            Type currentType = _target.GetType(); 
                            Type targetType = declaringType.GetGenericTypeDefinition(); 
                            while (currentType != null)
                            { 
                                if (currentType.IsGenericType &&
                                    currentType.GetGenericTypeDefinition() == targetType)
                                {
                                    declaringType = currentType as RuntimeType; 
                                    break;
                                } 
                                currentType = currentType.BaseType; 
                            }

                            BCLDebug.Assert(currentType != null || _target.GetType().IsCOMObject, "The class hierarchy should declare the method"); 
                        }
                        else 
                        { 
                            MethodInfo invoke = this.GetType().GetMethod("Invoke"); 
                            declaringType = (RuntimeType)invoke.GetParameters()[0].ParameterType;
                        }
                    }
                } 
                _methodBase = (MethodInfo)RuntimeType.GetMethodBase(declaringType, method);
            } 
            return (MethodInfo)_methodBase; 
        }

  以上是System.Delegate類中的定義,接下來看一下MulticastDelegate重寫:

[System.Security.SecuritySafeCritical] 
        protected override MethodInfo GetMethodImpl()
        { 
            if (_invocationCount != (IntPtr)0 && _invocationList != null) 
            {
                Object[] invocationList = _invocationList as Object[];
                if (invocationList != null)
                {
                    int index = (int)_invocationCount - 1; 
                    return ((Delegate)invocationList[index]).Method;
                } 
                MulticastDelegate innerDelegate = _invocationList as MulticastDelegate; 
                if (innerDelegate != null)
                { 
                    return innerDelegate.GetMethodImpl();
                }
            } 
            else if (IsUnmanagedFunctionPtr())
            { 
                if ((_methodBase == null) || !(_methodBase is MethodInfo)) 
                {
                    IRuntimeMethodInfo method = FindMethodHandle();
                    RuntimeType declaringType = RuntimeMethodHandle.GetDeclaringType(method);
                    if (RuntimeTypeHandle.IsGenericTypeDefinition(declaringType) || RuntimeTypeHandle.HasInstantiation(declaringType)) 
                    { 
                        RuntimeType reflectedType = GetType() as RuntimeType; 
                        declaringType = reflectedType;
                    }
                    _methodBase = (MethodInfo)RuntimeType.GetMethodBase(declaringType, method);
                } 
                return (MethodInfo)_methodBase;
            } 
            return base.GetMethodImpl(); 
        }

 以上是對(duì)委托的相關(guān)定義,以及有關(guān)委托的一些操作方法的說明,沒有具體指出如何去創(chuàng)建和使用委托,因?yàn)槲械暮唵蝿?chuàng)建和一般應(yīng)用,對(duì)于大部分開發(fā)者來說是相對(duì)較為簡單的,因?yàn)槲④浽诓粩嗟膶?duì)C#的語法進(jìn)行提升和修改,極大的簡化了對(duì)應(yīng)的操作。但是正是由于在應(yīng)用層做了較大的封裝,這也會(huì)導(dǎo)致特性在底層的復(fù)雜度慢慢的增大。

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。

文章題目:C#中的委托解析-創(chuàng)新互聯(lián)
文章轉(zhuǎn)載:http://aaarwkj.com/article48/pgihp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、網(wǎng)頁設(shè)計(jì)公司、響應(yīng)式網(wǎng)站、關(guān)鍵詞優(yōu)化、搜索引擎優(yōu)化、網(wǎng)站營銷

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計(jì)
亚洲欧美中文字幕乱码| 日本精品在线不卡视频| 亚洲天堂av成人在线观看| 亚洲乱码一区二区免费版| 亚洲精品成人久久网| av东京热狠狠男人的天堂| 久久夜色噜噜噜av一区| 亚洲一区欧美日韩91| 精品一区中文字幕少妇人妻| 99精品国产综合久久麻豆| 成人18禁h黄在线看免费| 日韩国产精品一区二区| 日韩专区亚洲专区欧美专区| 国产一区二区精品小视频| 亚洲精品一区二区三区小| 精品人妻少妇免费久久蜜臀av| 午夜欧美日韩精品久久久| 亚洲国产一区二区精品| 国产欧美激情一区二区 | 在线中文字幕日韩有码| 男人的天堂av最新版本| 欧美精品成人免费在线| 一区二区三区国产不卡| 欧美亚洲五月婷婷激情| 国产成人亚洲一区二区三区| 日韩一级精品电影网| 国产一区二区精品小视频| 国产精品成人一区二区三| 午夜欧美日韩精品久久久| 高清免费在线自偷自拍| 亚洲日本日本午夜精品| 欧美夫妻成人性生活视频| 91天美精东果冻麻豆| 国产999精品在线观看| 亚洲伊人久久一区二区| 国产日韩欧美精品激情| 最新日本人妻中文字幕| 热99精品视频在线观看| 97人妻人人揉人人澡人人学生| 99精品国产综合久久麻豆| 亚洲成人大片免费在线观看|