out参数,ref参数,params参数数组
params参数数组
params关键字可以为方法指定数目可变的参数。params关键字修饰的参数,可以传入任意数目的同类型参数,甚至可以不传入参数。
不过params修饰的参数必须是方法的最后一个参数,并且一个方法只能有一个params修饰的参数。
示例
public class MyClass
{
public static void UseParams(params int[] list)
{
for (int i = 0; i < list.Length; i++)
{
Console.Write(list[i] + " ");
}
Console.WriteLine();
} public static void UseParams2(params object[] list)
{
for (int i = 0; i < list.Length; i++)
{
Console.Write(list[i] + " ");
}
Console.WriteLine();
} static void Main()
{
// You can send a comma-separated list of arguments of the
// specified type.
UseParams(1, 2, 3, 4);
UseParams2(1, 'a', "test"); // A params parameter accepts zero or more arguments.
// The following calling statement displays only a blank line.
UseParams2(); // An array argument can be passed, as long as the array
// type matches the parameter type of the method being called.
int[] myIntArray = { 5, 6, 7, 8, 9 };
UseParams(myIntArray); object[] myObjArray = { 2, 'b', "test", "again" };
UseParams2(myObjArray); // The following call causes a compiler error because the object
// array cannot be converted into an integer array.
//UseParams(myObjArray); // The following call does not cause an error, but the entire
// integer array becomes the first element of the params array.
UseParams2(myIntArray);
}
}
/*
Output:
1 2 3 4
1 a test 5 6 7 8 9
2 b test again
System.Int32[]
*/
该示例中,UseParams方法可以接受任意数目的int类型参数,UseParams2方法可以接受任意数目的object类型参数。
ref引用参数
ref关键字使参数通过引用传递(非值传递)。通过引用传递参数的效果是:在方法中对参数的任何改变都会保留。
说明:引用传递和引用类型是两个概念,不要混淆。值类型和引用类型都可以用ref修饰,当通过引用传递时,不会对值类型装箱。
若要使用ref参数,方法的定义和调用都必须显式使用ref关键字,如下所示:
class RefExample {
static void Method(ref int i) {
// Rest the mouse pointer over i to verify that it is an int.
// The following statement would cause a compiler error if i
// were boxed as an object.
i = i + 44;
}
static void Main() {
int val = 1;
Method(ref val);
Console.WriteLine(val);
// Output: 45
}
}
传递给ref形参的实参必须先经过初始化才能使用。这与out形参不同,out形参使用前可以不初始化。
同一个类中的方法签名,差别不能仅仅是参数修饰分别为ref和out。如果两个方法之间的差别仅在于,一个为ref参数,另一个为out参数,则会发生编译错误。例如,下面的代码会编译出错:
class CS0663_Example
{
// Compiler error CS0663: "Cannot define overloaded
// methods that differ only on ref and out".
public void SampleMethod(out int i) { }
public void SampleMethod(ref int i) { }
}
不过,有ref(out)和没ref(out)的函数可以重载,如下所示,可以通过编译:
class RefOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(ref int i) { }
}
属性不是变量,它们是方法,所以不能作为ref参数传递。
下面类型的方法不能使用ref和out关键字:
- 异步方法,即以async修饰符修饰的方法。
- 迭代器方法,包括yield return 或 yield break 声明语句。
out输出参数
在ref中已经对out有所介绍,下面对out参数进行详细解析。out关键字可以应用在两个地方:参数修饰符;接口或委托中修饰泛型类型参数。首先介绍参数修饰符部分。
参数修饰
out关键字通过引用传递参数。这与ref关键字相似,不过ref要求在传递之前初始化而变量,out没有此要求。和ref一样,方法定义和调用处都必须显式使用out关键字。例如:
class OutExample
{
static void Method(out int i)
{
i = 44;
}
static void Main()
{
int value;
Method(out value);
// value is now 44
}
}
虽然out参数传递的变量无需在传递之前初始化,但需要在方法返回之前赋值。
示例
如果希望方法返回多个值,可以声明out方法。下面的示例使用out返回具有单个方法调用的三个变量。注意,第三个参数赋为null值,这使得方法可以由选择地返回值。
class OutReturnExample
{
static void Method(out int i, out string s1, out string s2)
{
i = 44;
s1 = "I've been returned";
s2 = null;
}
static void Main()
{
int value;
string str1, str2;
Method(out value, out str1, out str2);
// value is now 44
// str1 is now "I've been returned"
// str2 is (still) null;
}
}
泛型修饰符
对于泛型类型参数,out关键字可指定该类型参数是协变的。可以在泛型接口和委托中使用out关键字。
通过协变,可以使用比指定类型派生程度更大的类型。这样可以对委托类型和实现变体接口的类进行隐式转换。引用类型支持协变和逆变,值类型不支持。
如果接口具有协变类型形参,则允许其返回派生程度更大的实参。例如,.NET framework 4中的IEnumerable<T>接口,其类型T是协变的,因此无需使用任何特殊的转换方法就可以将IEnumerable<Of String>类型的对象分配给IEnumerable<Of Object>类型的对象。
可以向协变委托分配同一类型的其他委托,但需使用派生程序更大的泛型类型参数。
示例
下面演示如何声明、扩展和实现一个协变泛型接口。此外还演示如何对实现协变接口的类使用隐式转换。
// Covariant interface.
interface ICovariant<out R> { } // Extending covariant interface.
interface IExtCovariant<out R> : ICovariant<R> { } // Implementing covariant interface.
class Sample<R> : ICovariant<R> { } class Program
{
static void Test()
{
ICovariant<Object> iobj = new Sample<Object>();
ICovariant<String> istr = new Sample<String>(); // You can assign istr to iobj because
// the ICovariant interface is covariant.
iobj = istr;
}
}
在泛型接口中,当符合下列条件,可将类型参数声明为协变的
- 类型形参仅用作接口方法的返回类型,不用作方法实参的类型。
说明:此规则有个例外,如果在协变接口中,包含用作方法参数的逆变泛型委托,则可以将协变类型用作此委托类型参数。 - 类型参数不用作接口方法的泛型约束。
下面演示如何声明、实例化和调用一个协变泛型委托:
// Covariant delegate.
public delegate R DCovariant<out R>(); // Methods that match the delegate signature.
public static Control SampleControl()
{ return new Control(); } public static Button SampleButton()
{ return new Button(); } public void Test()
{
// Instantiate the delegates with the methods.
DCovariant<Control> dControl = SampleControl;
DCovariant<Button> dButton = SampleButton; // You can assign dButton to dControl
// because the DCovariant delegate is covariant.
dControl = dButton; // Invoke the delegate.
dControl();
}
在泛型委托中,如果类型仅用作方法返回类型,且不用于方法参数,则可声明为协变的。
out参数,ref参数,params参数数组的更多相关文章
- C# 中out,ref,params参数的使用
C#中有三个高级参数,分别是out,ref,params: 1.out参数 方法使用return 只能返回一个值(一个数值或一个指针值),out参数可以帮助我们在一个方法中返回多个值,不限类型. ...
- C# 方法的out、ref、params参数
一.out参数实例 [实例]求一个数组中的最大值.最小值.总和.平均值 class Program { static void Main(string[] args) { //写一个方法 求一个数组中 ...
- C#中引用参数ref和输出参数out
引用参数 用于按引用传递自变量. 为引用参数传递的自变量必须是具有明确值的变量,并且在方法执行期间,引用参数指明的存储位置与自变量相同. 引用参数使用 ref 修饰符进行声明. 输出参数 用于按引用传 ...
- 基于params,ref,out的参数问题详解
http://www.jb51.net/article/37967.htm 最近在写程序时遇到params,ref,out 参数问题.回头有自习看了看MSDN,才巩固了基础.现在和大家分享一下.par ...
- c#.net中参数修饰符ref,out ,params解析
params ============================================================================================= ...
- C# 参考之方法参数关键字:params、ref及out
如果在为方法声明参数时未使用 ref 或 out,则该参数可以具有关联的值.可以在方法中更改该值,但当控制传递回调用过程时,不会保留更改的值.通过使用方法参数关键字,可以更改这种行为. params ...
- c#中的ref、out、params参数
out参数 与c++的引用的对比 out参数可以用来传递方法返回值,与c++中的引用有点像,但是还有有些不同: - 调用方法的时候必须写out参数 - 调用方法之前必须先分配空间 - 调用方法之前不用 ...
- 【又长见识了】函数传参,params参数,ref和out参数详解
一.原来函数这样传参 先看一个函数和函数调用. static void Main(string[] args) { ; Test(num);//局部变量在使用之前赋值 //Test(10); //直接 ...
- 参数修饰符ref,out ,params的区别
参数修饰符ref,out ,params的区别 C#中有三个关键字-ref,out ,params,可是这三个之间的区别你都明白了吗? 那么我们就来认识一下参数修饰符ref,out ,params吧, ...
随机推荐
- VC只运行一个程序实例
方法有很多,以下只是提供一种用的多的 一. 单文档程序 在程序App类的InitInstance中添加如下代码 BOOL CDDZApp::InitInstance() { /*只运行一个实例*/ / ...
- c#新手之1-如何组织类及相互调用
不知道这个文章的名字起的对不对,姑且这么叫吧.我在这之前用c语言写程序几乎很少用函数调用来解决问题,都是用全局变量然后面向过程对数据做简单的处理,这就造成了我在学习c@之后仍有这个毛病,好点的时候有个 ...
- Android FM模块学习之四源码分析(3)
接着看FM模块的其他几个次要的类的源码.这样来看FM上层的东西不是太多. 请看android\vendor\qcom\opensource\fm\fmapp2\src\com\caf\fmradio\ ...
- nat转换
实验目的: (1) 了解nat转换 (2) 了解nat转换配置命令 (3) 了解哪些是私有ip地址哪些不是私有ip地址 实验工具: 华为eNSP模拟器和Wireshar 实验拓 ...
- 对于unallocated space的翻译 我想说几句话
在sqlserver中,当我们使用sp_spaceused查看数据库空间使用情况的时候 会看到属性unallocated space.所有的中文翻译都是“未保留供数据库对象使用的数据库空间”, 作为中 ...
- Java笔记5-修饰符,重载,递归,数组
方法的定义修饰符 返回类型 方法名(参数列表) throws 异常类型列表 { //方法体}==如何来设计一个方法:案例:请根据如下的业务分别设计出方法1.根据给定的年份判断是否是闰年?public ...
- springMVC返回json
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> < ...
- 关于HTML标签(元素)的那些事?
关于HTML标签(元素)的那些事? 在战场上,知己知彼,方能百战百胜:在商场上,知己知彼,亦能呼风唤雨:在情场上,知己知彼,才能幸福美满.当然啦,在我们前端开发上,亦要知己知彼,才能叱咤风云.关于HT ...
- 2015.12.29~2015.12.30真题回顾!-- HTML5学堂
2015.12.29~2015.12.30真题回顾!-- HTML5学堂 吃饭,能够解决饥饿,提供身体运作机能.练习就像吃饭,强壮自己,提升编程技能,寻求编程技巧的最佳捷径!吃饭不能停,练习同样不能停 ...
- ArcGIS+API+for+JS测距
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...