函式傳參,params引數,ref和out引數詳解

2021-09-10 12:00:22 字數 3906 閱讀 8776

一、原來函式這樣傳參

先看乙個函式和函式呼叫。

複製**

static void main(string args)

static void test(int i)//i 相當於乙個區域性變數

複製**

test函式定義了乙個int 型別的變數i作為引數,這個地方相當於宣告了乙個區域性變數,而區域性變數使用之前必須賦值,這就是為什麼函式使用的時候要賦值(傳乙個值進去)。

假如不想給引數賦值怎麼辦?那就在函式宣告引數的時候給引數(區域性變數)賦值,這樣呼叫函式的時候就可以不給引數傳值。如下:

複製**

static void main(string args)

static int test(int i=10)//為區域性變數賦值,傳引數的時候可以不為i賦值

複製**

注意:賦初值的引數必須放在引數列表最右側,可以有多個帶初值的引數。

作用:為引數賦了初值,在呼叫的時候可以賦值也可以不賦值,作用是為引數指定預設值,。

static void  test(int a,int b=20, int i=10)

在為方法傳引數的時候必須按照引數宣告的順序傳,這個一直是這樣做的,也沒多想過,其實也可以不按照傳參的順序,如下:

複製**

static void main(string args)

static void test2(int i,string s,bool b)

複製**

傳參的時候指定哪個引數傳什麼值就可以不按照順序傳參,這個不是很常用,但是以前不知道,又長見識了。

複製**

static void main(string args)

static int test(int i )

static int test(int a,int b=20)

static int test(int a,int b=20,int c=30)

複製**

當有過載的時候,不給帶有預設值引數賦值,他會優先執行,不帶預設引數的函式。

二、params 引數陣列(可變引數)

我們知道陣列的長度是不可變的。當我們把乙個陣列作為引數傳遞的時候,想改變陣列長度不是一件容易的事兒。params 引數陣列就可以隨便指定引數長度,也不用在傳參的時候去特意定義乙個陣列傳參。使用非常方便。

例:複製**

static void main(string args)

;test1(arr);

console.writeline();

test2(1,2,4,56,78,8,4);

console.writeline();

test2(1,5,7);

console.read();

}static void test1(int arr )

}static void test2(params int arr) //params 陣列

}複製**

params 引數陣列,作為引數的時候,引數個數是可變的,當然也可以為0,但是用params 引數陣列的時候,乙個函式裡只有乙個params引數,並且必須放在引數列表的最後。

params用法: 1、用來修飾方法的引數,而且只能修飾一維陣列;

2、乙個方法只能出現乙個params引數,並且必須把params引數陣列放在最後,不能帶有預設值;

3、呼叫方法的時候,params修飾的引數,可以傳乙個陣列,也可以傳陣列的元素,也可以什麼都不傳(長度就為0);

在控制台應用程式中,如console.writeline(「我叫,今年歲,喜歡」,「vivu」,「22」,「c#」);其實就用到了params引數,這個過載就是:

console.writeline(string.format,params string arr);

總結:params 引數修飾的陣列相當於長度可變的引數陣列。它是修飾引數(一維陣列)的乙個關鍵字。用處就是在不知道引數個數或引數個數有可能發生變化的情況下使用。

三、ref和out引數修飾符

ref:

值型別在傳遞值的時候,只是複製了乙份值賦給另乙個變數,另乙個變數改變並不能改變原有的值。例如:

int num = 200;

int a = num;

a -= 100;

console.writeline(num);//輸出200

console.writeline(a);//輸出100

但是,假如num代表我錢包裡的錢,我把錢包交給別人(int a=num),別人用了100(a-=100),這時候,我錢包裡的錢(num)應該是多少?按照上面的方式執行就會出錯,錢包裡的錢是不會變的,因為在傳值的時候只是複製了num的乙份值給a,a改變並不會改變num的值。那該怎麼辦???

如果我傳遞的值是num的引用(可以理解為位址),那麼a 改變了num就也會改變了。但是int 型別是值傳遞,怎麼辦,把它變為引用就要用到ref和out引數。

ref和out引數的作用就是把值傳遞改為引用傳遞。

改寫上面的錢包的例子。

複製**

static void main(string args)

static int test(ref int a)

複製**

在記憶體圖中分析一下ref引數:

ref引數可以按引用型別傳遞,如果ref修飾的是引用型別的引數呢?先看下面的例子:

先建立乙個person類

person類

再看一下面ref修飾引用型別的情況。

複製**

static void main(string args)

;test1§;

console.writeline(p.name); //輸出什麼???

testref1(ref p);

console.writeline(p.name); //輸出什麼???

test2§;

console.writeline(p.name); //輸出什麼???

testref2(ref p);

console.writeline(p.name); //輸出什麼???

console.read();

}static void test1(person p);}

static void testref1(ref person p);}

static void test2(person p)

static void testref2(ref person p)

複製**

輸出結果是,紅紅,藍藍,嘿嘿,掰掰。畫一下記憶體圖很好分析。引用型別本來傳遞的就是位址,所以引用型別使用ref引數和不使用是一樣的。這裡偷一下懶,想知道的去執行,畫一下記憶體圖吧!!!

ref用法:1、使用ref必須在引數宣告和呼叫的時候都帶上ref關鍵字;

2、只能修飾變數,不能修飾常量;

3、ref在方法中可以對ref修飾的值不改變,但是在傳參前必須給引數賦值;

out:

ref 在使用之前必須賦初始值,它主要側重於改變,修改值。使用ref,在函式宣告與呼叫的時候必須在引數前面加上ref。out引數的作用與使用方法與ref類似,與ref不同的是out在使用前不必賦初始值,但在返回的時候必須為他賦值,所以out主要側重於輸出。out修飾符引數例子:

複製**

static void main(string args)

static int testout(int a,out int b)

複製**

總結:ref和out引數修飾符,都是把引數按引用型別傳遞,但是ref側重於改變值,而out側重於輸出。乙個函式只有乙個輸出值,但想返回多個值的時候就用out引數修飾符。

ref在使用之前必須賦值,out在返回之前必須賦值。ref和out在函式使用和呼叫的時候,引數前面必須加ref和out引數

params傳參和query傳參

params傳參 this.router.push query傳參 this.router.push 1 用法上的 query要用path來引入,params要用name來引入,接收引數都是類似的,分別是this.route.query.name和this.route.params.name。注意接...

params傳參和query傳參

當你使用params方法傳參的時候,要在路由後面加引數名,並且傳參的時候,引數名要跟路由後面設定的引數名對應。使用query方法,就沒有這種限制,直接在跳轉裡面用就可以。注意 如果路由上面不寫引數,也是可以傳過去的,但不會在url上面顯示出你的引數,並且當你跳到別的頁面或者重新整理頁面的時候引數會丟...

out和ref引數,params可變引數

protected void page load object sender,eventargs e intmin,max outparatest nums,out min,out max response.write 最小值 min 0 response.write 最大值 max 9 ref 將...