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

有關(guān).NET參數(shù)傳遞的方式引發(fā)的思考

 更新時(shí)間:2016年12月27日 09:30:23   作者:彭澤0902  
在.NET中參數(shù)的使用方法主要為可選參數(shù)、命名參數(shù)、可變數(shù)量參數(shù)等等。本文也是主要介紹這三種參數(shù)的使用方法

下面就簡(jiǎn)單的介紹一下.NET的一些常用參數(shù)用法,如有不足還望指正,也歡迎大家在下面留言討論,分享自己的見解。

一.DotNet參數(shù)概述:

    .NET中參數(shù)(形式參數(shù))變量是方法或索引器聲明的一部分,而實(shí)參是調(diào)用方法或索引器時(shí)使用的表達(dá)式。

    在CLR中,默認(rèn)的情況下所有的方法參數(shù)都是傳值的。在傳遞引用類型的對(duì)象時(shí),對(duì)一個(gè)對(duì)象的引用會(huì)傳遞給方法。這里的船引用本身是以傳值的方式傳給方法的。這也意味著方法能夠修改對(duì)象,而調(diào)用者能看到這些修改。對(duì)于值類型的實(shí)例,傳給方法的實(shí)例的一個(gè)副本。意味著方法將獲得它專用的一個(gè)值類型實(shí)例副本,調(diào)用者中的實(shí)例不受影響。

    在CLR中允許以傳引用而非傳值的方式傳遞參數(shù),在C#中使用out和ref來實(shí)現(xiàn)傳遞引用的方式傳值。在C#中使用out和ref來實(shí)現(xiàn)傳遞引用的方式傳值,這兩個(gè)關(guān)鍵字告訴編譯器生成元數(shù)據(jù)來指明該參數(shù)是傳引用的,編譯器將生成代碼來傳遞參數(shù)的地址,而不是傳遞參數(shù)本身。為值類型使用out和ref,效果等同于以傳值的方式傳遞引用類型。  

    常用的參數(shù)主要有基本類型參數(shù),泛型參數(shù),以及<in T>和<out T>,dynamic等等。例如<in T>和<out T>,在CLR中支持泛型類型的可變性,C#在4.0時(shí)獲得了生命泛型遍體所必須的語(yǔ)法,并且現(xiàn)在編譯器也能夠知道接口和委托可能的轉(zhuǎn)換??勺冃允且砸环N類型安全的方式,講一個(gè)對(duì)象作為另一個(gè)對(duì)象來使用。可變性應(yīng)用于泛型接口和泛型委托的類型參數(shù)中。協(xié)變形用于向調(diào)用者返回某項(xiàng)操作的值;逆變性是指調(diào)用者想API傳入值;不變性是相對(duì)于協(xié)變性和逆變性,是指什么也不會(huì)發(fā)生。對(duì)于這方面的知識(shí)非常的豐富,有興趣的可以自行了解,這里就不做詳細(xì)的介紹了。dynamic類型,C#是一門靜態(tài)類型的語(yǔ)言,在某些情況下,C#編譯器要尋找特定的名稱而不是接口。dynamic可以在編譯時(shí)做任何事,到執(zhí)行時(shí)再由框架進(jìn)行處理。有關(guān)動(dòng)態(tài)類型的介紹也不做更深入的介紹。

    在.NET中參數(shù)的使用方法主要為可選參數(shù)、命名參數(shù)、可變數(shù)量參數(shù)等等。本文下面也是主要介紹這三種參數(shù)的使用方法。

二.DotNet參數(shù)用法:

    以下是主要介紹三種參數(shù)的用法:可選參數(shù);命名實(shí)參;傳遞可變數(shù)量的參數(shù)。  

   1.可選參數(shù):

     (1).基本用法:

        如果某個(gè)操作需要多個(gè)值,而有些值在每次調(diào)用的時(shí)候又往往是相同的,這時(shí)通??梢允褂每蛇x參數(shù)。在C#以前實(shí)現(xiàn)可變參數(shù)的功能,往往聲明一個(gè)包含所有可能參數(shù)的方法,其他方法調(diào)用這個(gè)方法,并傳遞恰當(dāng)?shù)哪J(rèn)值。

        在可選參數(shù)中,設(shè)計(jì)一個(gè)方法的參數(shù)時(shí),可以為部分或全部參數(shù)分配默認(rèn)值。在調(diào)用這些方法代碼可以選擇不指定部分實(shí)參,接受默認(rèn)值。還可以在調(diào)用方法時(shí),還可以通過指定參數(shù)名稱的方式為其傳遞實(shí)參。如下實(shí)例:

 static void OptionalParameters(int x, int y = 10, int z = 20)
  {
   Console.WriteLine("x={0} y={1} z={2}",x,y,z);
  }
    
 OptionalParameters(1, 2, 3);
   OptionalParameters(1, 2);
   OptionalParameters(1);

     以上的例子可以很清楚的看到其用法,int y=10和int z=20這兩個(gè)參數(shù)就是可選參數(shù)??蛇x參數(shù)的使用中,如果調(diào)用時(shí)省略了一個(gè)參數(shù),C#編譯器會(huì)自動(dòng)嵌入?yún)?shù)的默認(rèn)值。向方法傳遞實(shí)參時(shí),編譯器按從左向右的順序?qū)?shí)參進(jìn)行求值。使用已命名的參數(shù)傳遞實(shí)參時(shí),編譯器仍然按照從左到右的順序?qū)?shí)參進(jìn)行求值。

      (2).基本原則:

       可選參數(shù)包含一些規(guī)范,具體的一些要求如下:

    (a).所有可選參數(shù)必須出現(xiàn)在必備參數(shù)之后,參數(shù)數(shù)組(使用params修飾符聲明)除外,但他們必須出現(xiàn)在參數(shù)列表的最后,在他們之前是可選參數(shù)。

    (b).參數(shù)數(shù)組不能聲明為可選的,如果調(diào)用者沒有指定值,將使用空數(shù)組代替。

    (c).可選參數(shù)不能使用ref和out修飾符。

    (d).可選參數(shù)可以為任何類型,但對(duì)于指定的默認(rèn)值卻有一些限制,那就是默認(rèn)值必須為常量(數(shù)字或字符串字面量、null、const成員、枚舉成員、default(T)操作符)。

    (e).指定的值會(huì)隱式轉(zhuǎn)換為參數(shù)類型,但是這種轉(zhuǎn)換不能是用戶定義的。

    (f).可以為方法、構(gòu)造器、有參屬性的參數(shù)指定默認(rèn)值,還可以為屬于委托定一部分的參數(shù)指定默認(rèn)值。

    (g).C#不允許省略逗號(hào)之間的實(shí)參。

      在使用可選參數(shù)時(shí),對(duì)于引用類型使用null來做默認(rèn)值,如果參數(shù)類型是值類型,只需要使用相應(yīng)的可空值類型作為默認(rèn)值。

      (3).代碼示例:  

 /// <summary>
  /// 提取異常及其內(nèi)部異常堆棧跟蹤
  /// </summary>
  /// <param name="exception">提取的例外</param>
  /// <param name="lastStackTrace">最后提取的堆棧跟蹤(對(duì)于遞歸), String.Empty or null</param>
  /// <param name="exCount">提取的堆棧數(shù)(對(duì)于遞歸)</param>
  /// <returns>Syste.String</returns>
  public static string ExtractAllStackTrace(this Exception exception, string lastStackTrace = null, int exCount = 1)
  {
   while (true)
   {
    var ex = exception;
    const string entryFormat = "#{0}: {1}\r\n{2}";
    lastStackTrace = lastStackTrace ?? string.Empty;
    lastStackTrace += string.Format(entryFormat, exCount, ex.Message, ex.StackTrace);
    if (exception.Data.Count > 0)
    {
     lastStackTrace += "\r\n Data: ";
     lastStackTrace = exception.Data.Cast<DictionaryEntry>().Aggregate(lastStackTrace, (current, entry) => current + $"\r\n\t{entry.Key}: {exception.Data[entry.Key]}");
    }
    //遞歸添加內(nèi)部異常
    if ((ex = ex.InnerException) == null) return lastStackTrace;
    exception = ex;
    lastStackTrace = $"{lastStackTrace}\r\n\r\n";
    exCount = ++exCount;
   }
  }

   2.命名實(shí)參:

         以上講解了可選參數(shù)的一些基本概念和用法,接下來看一下命名參數(shù)的相關(guān)操作用法:

      (1).基本用法:

          命名實(shí)參是指在指定實(shí)參的值時(shí),可以同時(shí)指定相應(yīng)的參數(shù)名稱。編譯器將判斷參數(shù)的名稱是否正確,并將指定的值賦給這個(gè)參數(shù)。命名參數(shù)在各個(gè)實(shí)參之前加上它們的參數(shù)名稱以及一個(gè)冒號(hào)。如下代碼:

new StreamWriter(path:filename,aooend:true,encoding:realEncoding);

如果要對(duì)包含ref和out的參數(shù)指定名稱,需要將ref和out修飾符放在名稱之后,實(shí)參之前。

int number;
bool success=int.TryParse("10",result:out number);

      (2).基本原則:

        在命名參數(shù)中,所有的命名參數(shù)必須位于位置實(shí)參之后,兩者之間的位置不能改變。位置實(shí)參總是指向方法聲明中相應(yīng)的參數(shù),不能跳過參數(shù)之后,在通過命名相應(yīng)位置的實(shí)參來指定。實(shí)參仍然按編寫順序求值,即使這個(gè)順序有可能會(huì)不同于參數(shù)的聲明順序。

        在一般情況下,可選參數(shù)與命名實(shí)參會(huì)一起配合使用。可選參數(shù)會(huì)增加適用方法的數(shù)量,而命名實(shí)參會(huì)減少使用方法的數(shù)量。為了檢查是否存在特定的適用方法,編譯器會(huì)使用位置參數(shù)的順序構(gòu)建一個(gè)傳入實(shí)參的列表,然后對(duì)命名實(shí)參和剩余的參數(shù)進(jìn)行匹配。如果沒有指定某個(gè)必備參數(shù),或某個(gè)命名實(shí)參不能與剩余的參數(shù)相匹配,那么這個(gè)方法就不是適用的。

       命名實(shí)參有時(shí)可以代替強(qiáng)制轉(zhuǎn)換,來輔助編譯器進(jìn)行重載決策。如果方法是從模塊的外部調(diào)用的,更改參數(shù)的默認(rèn)值是具有潛在的危險(xiǎn)的??梢园疵Q將實(shí)參傳給沒有默認(rèn)值的參數(shù),但是編譯器要想編譯代碼,所有要求的實(shí)參都必須傳遞。

       在寫C#代碼與COM對(duì)象模型進(jìn)行互操作時(shí),C#的可選參數(shù)和命名參數(shù)功能是最好用的,調(diào)用一個(gè)COM組件時(shí),為了以傳引用的方式傳遞一個(gè)實(shí)參,C#還允許省略REF/OUT,在嗲用COM組件時(shí),C#要求必須向?qū)崊?yīng)用OUT.REF關(guān)鍵字。   

   3.傳遞可變數(shù)量的參數(shù):

      在項(xiàng)目開發(fā)中,有時(shí)我們需要定義一個(gè)方法來獲取可變數(shù)量的參數(shù)??梢允褂胮arams,params只能應(yīng)用于方法簽名中的最后一個(gè)參數(shù)。params關(guān)鍵字告訴編譯器向參數(shù)應(yīng)用System.ParamArrayAttribute的實(shí)例。我們具體看一下實(shí)現(xiàn)的代碼:

[AttributeUsage(AttributeTargets.Parameter, Inherited=true, AllowMultiple=false), ComVisible(true), __DynamicallyInvokable]
public sealed class ParamArrayAttribute : Attribute
{
 // Methods
 [__DynamicallyInvokable]
 public ParamArrayAttribute();
}
[__DynamicallyInvokable]
public ParamArrayAttribute()
{
}

     以上的代碼可以看出該類繼承自Attribute類,對(duì)于Attribute類可能不會(huì)陌生,那就是定義定制屬性的基類,說明ParamArrayAttribute類用于定義定制屬性,ParamArrayAttribute類在System命名空間下,ParamArrayAttribute類只有一個(gè)構(gòu)造方法,沒有具體的實(shí)現(xiàn)。AttributeUsage也定義了屬性的使用方式。

    C#編譯器檢測(cè)到一個(gè)方法調(diào)用時(shí),會(huì)檢查所有具有指定名稱、同時(shí)參數(shù)沒有應(yīng)用ParamArrayAttribute的方法。如果找到一個(gè)匹配的方法,編譯器生成調(diào)用它所需的代碼。如果編譯器沒有找到一個(gè)匹配的方法,會(huì)直接檢查應(yīng)用ParamArrayAttribute的方法。如果找到一個(gè)匹配的方法,編譯器會(huì)先生成代碼來構(gòu)造一個(gè)數(shù)組,填充它的元素,再生成代碼來調(diào)用選定的方法。

    調(diào)用一個(gè)參數(shù)數(shù)量可變的方法時(shí),會(huì)造成一些額外的性能損失,數(shù)組對(duì)象必須在對(duì)上分配,數(shù)組元素必須初始化,而且數(shù)組的內(nèi)存最終必須垃圾回收。

    提供一個(gè)方法代碼,僅供參考:     

 /// <summary>
  /// 字符型二維數(shù)組轉(zhuǎn)換成DataTable 
  /// </summary>
  /// <param name="stringDyadicArray"></param>
  /// <param name="messageOut"></param>
  /// <param name="dataTableColumnsName"></param>
  /// <returns></returns>
  public DataTable DyadicArrayToDataTable(string[,] stringDyadicArray, out bool messageOut,
   params object[] dataTableColumnsName)
  {
   if (stringDyadicArray == null)
   {
    throw new ArgumentNullException("stringDyadicArray");
   }
   var returnDataTable = new DataTable();
   if (dataTableColumnsName.Length != stringDyadicArray.GetLength(1))
   {
    messageOut = false;
    return returnDataTable;
   }
   for (var dataTableColumnsCount = 0;dataTableColumnsCount < dataTableColumnsName.Length;dataTableColumnsCount++)
   {
    returnDataTable.Columns.Add(dataTableColumnsName[dataTableColumnsCount].ToString());
   }
   for (var dyadicArrayRow = 0; dyadicArrayRow < stringDyadicArray.GetLength(0); dyadicArrayRow++)
   {
    var addDataRow = returnDataTable.NewRow();
    for (var dyadicArrayColumns = 0; dyadicArrayColumns < stringDyadicArray.GetLength(1);dyadicArrayColumns++)
    {
     addDataRow[dataTableColumnsName[dyadicArrayColumns].ToString()] = stringDyadicArray[dyadicArrayRow, dyadicArrayColumns];
    }
    returnDataTable.Rows.Add(addDataRow);
   }
   messageOut = true;
   return returnDataTable;
  }

   以上給出了一個(gè)使用可變參數(shù)數(shù)量以及命名參數(shù)的使用樣例,完成了將二維字節(jié)數(shù)組轉(zhuǎn)化為DataTable對(duì)象,將數(shù)組進(jìn)行遍歷,并將數(shù)組寫入datatable中,對(duì)于整個(gè)方法的邏輯就不做深入介紹,代碼比較的簡(jiǎn)單。

三.與參數(shù)有關(guān)的一些指導(dǎo)原則:

    聲明方法的參數(shù)類型時(shí),應(yīng)盡量指定最弱的類型,最好是接口而不是基類。

    在設(shè)計(jì)模式的基本原則中,迪米特法則也較最少知識(shí)原則,迪米特法則是指如果兩個(gè)類不必彼此直接通信,那么這兩個(gè)類就不應(yīng)當(dāng)直接的相互作用。如果其中一個(gè)類需要調(diào)用另一個(gè)類的某一個(gè)方法的話,可以通過第三者轉(zhuǎn)發(fā)這個(gè)調(diào)用。在類結(jié)構(gòu)的設(shè)計(jì)上,每一個(gè)類都應(yīng)當(dāng)盡量降低成員的訪問權(quán)限。類之間的耦合度越弱,越有利于復(fù)用,一個(gè)處在弱耦合的類被修改,不會(huì)對(duì)有關(guān)系的類造成波及。

    對(duì)于參數(shù)的使用中,我們?cè)趯?duì)參數(shù)類型的使用上,還是需要很仔細(xì)和認(rèn)真的去思考,因?yàn)樵趨?shù)類型的定義上,在一定程度上影響著我們程序的擴(kuò)展性和穩(wěn)定性,如果參數(shù)類型的約束比較大,對(duì)于后續(xù)方法的擴(kuò)展,意義是巨大的。在整個(gè)面向?qū)ο蟮恼Z(yǔ)言體系中,一切設(shè)計(jì)模式都是由“多態(tài)”延伸而來,對(duì)于接口和委托都是在我們面向?qū)ο笤O(shè)計(jì)中使用很多的,目的較多的是在使用時(shí)擴(kuò)大參數(shù)的約束性。

    在方法的返回值類型中,返回的類型應(yīng)該聲明為最強(qiáng)的類型,以免受限于特定的類型。

四.總結(jié):

   以上是一篇簡(jiǎn)單介紹方法參數(shù)的文章,在文章內(nèi)容中主要對(duì)于介紹可選參數(shù)、命名參數(shù)等。以上的內(nèi)容如果有不足的地方還望大家多多包涵,也希望能夠指出對(duì)應(yīng)的問題。知識(shí)先于模范,后于反思。學(xué)習(xí)完一點(diǎn)后,需要我們?nèi)タ偨Y(jié)和反思,其中的內(nèi)涵我們才會(huì)有時(shí)間和精力,以及由能力去思考。

以上所述是小編給大家介紹的有關(guān).NET參數(shù)傳遞的方式引發(fā)的思考,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • linq中的分組操作符

    linq中的分組操作符

    這篇文章介紹了linq中的分組操作符,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • 如何使用Python實(shí)現(xiàn)阿拉伯?dāng)?shù)字轉(zhuǎn)換成中國(guó)漢字

    如何使用Python實(shí)現(xiàn)阿拉伯?dāng)?shù)字轉(zhuǎn)換成中國(guó)漢字

    本文提供了一個(gè)Python代碼示例,用于將阿拉伯?dāng)?shù)字轉(zhuǎn)換為中文漢字表示,代碼定義了數(shù)字到漢字的映射表,并實(shí)現(xiàn)了處理不同位數(shù)(如個(gè)、十、百、千、萬(wàn)等)的函數(shù),特別地,處理方式包括對(duì)大數(shù)字的分解和轉(zhuǎn)換,以及對(duì)連續(xù)零的特殊處理,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • Visual Studio實(shí)現(xiàn)xml文件使用app.config、web.config等的智能提示

    Visual Studio實(shí)現(xiàn)xml文件使用app.config、web.config等的智能提示

    這篇文章主要為大家詳細(xì)介紹了Visual Studio中xml文件使用app.config、web.config等的智能提示方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • C#中的Equals、RefrenceEquals和==的區(qū)別與聯(lián)系

    C#中的Equals、RefrenceEquals和==的區(qū)別與聯(lián)系

    C#中判斷兩個(gè)對(duì)象是否相等有Equals、RefrenceEquals和==三種,其中==為運(yùn)算符,其它兩個(gè)為方法,而Equals又有兩種版本,一個(gè)是靜態(tài)的,一個(gè)是虛擬的,詳細(xì)了解可以參考本文
    2012-12-12
  • .net平臺(tái)推送ios消息的實(shí)現(xiàn)方法

    .net平臺(tái)推送ios消息的實(shí)現(xiàn)方法

    這篇文章主要介紹了.net平臺(tái)推送ios消息的實(shí)現(xiàn)方法,詳細(xì)講述了各個(gè)具體的實(shí)現(xiàn)步驟并附有源碼供大家參考之用,需要的朋友可以參考下
    2014-10-10
  • Asp.net導(dǎo)出Excel/Csv文本格式數(shù)據(jù)的方法

    Asp.net導(dǎo)出Excel/Csv文本格式數(shù)據(jù)的方法

    這篇文章主要介紹了Asp.net導(dǎo)出Excel/Csv文本格式數(shù)據(jù)的方法,比較實(shí)用,需要的朋友可以參考下
    2014-09-09
  • ASP.NET Core 9.0 中新增的MapStaticAssets() 中間件詳解

    ASP.NET Core 9.0 中新增的MapStaticAssets() 中

    文章介紹了ASP.NET Core 9.0新增的MapStaticAssets中間件,該中間件解決了UseStaticFiles存在的缺陷,如缺乏靜態(tài)資源傳輸壓縮、ETag低效緩存和缺乏指紋識(shí)別,它通過生成時(shí)間壓縮、基于內(nèi)容的ETags和指紋識(shí)別來提升性能,感興趣的朋友一起看看吧
    2024-12-12
  • 詳解.net core下如何簡(jiǎn)單構(gòu)建高可用服務(wù)集群

    詳解.net core下如何簡(jiǎn)單構(gòu)建高可用服務(wù)集群

    一說到集群服務(wù)相信對(duì)普通開發(fā)者來說肯定想到很復(fù)雜的事情,這篇文章主要介紹了詳解.net core下如何簡(jiǎn)單構(gòu)建高可用服務(wù)集群,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • ASP.NET頁(yè)面緩存常見的4種方式

    ASP.NET頁(yè)面緩存常見的4種方式

    這篇文章主要為大家詳細(xì)介紹了ASP.NET頁(yè)面緩存常見的4種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Visual Studio 2015全英界面切換成中文界面

    Visual Studio 2015全英界面切換成中文界面

    這篇文章主要為大家詳細(xì)介紹了Visual Studio 2015全英界面切換成中文界面的具體步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11

最新評(píng)論