关于传递参数 既采用引用传递又赋予默认值

时间:2022-01-20 09:52:01
1、如果采用ref的话就不能指定默认值:
void function(ref int arg)
{
}
这里无法指定 ref int arg = 0

2、如果采用指针的话倒是可以:
unsafe void function(int *arg = null)
{
}
但是,我需要修改项目属性勾上“支持不安全的代码块”,
并且所有需要调用function的函数都要定义为unsafe,这样我觉得可移植性太差……

3、重载:
void function(ref int arg)
{
}
void function()
{
}
其问题在于如果有多个这样的参数,重载的可能性就太多了,写起来不方便。

那么,请问有没有一种方法能克服上述的缺点,又满足“既采用引用传递又赋予默认值”呢?

10 个解决方案

#1


在C#语言层面上无解。

#2


不过你可以写一个reference type wrapper代替ref
class RefParam<T>
{
    public T Value { get; set; }
    public RefParam(T value) { Value = value; }
}

void function(RefParam<int> arg = default(RefParam<int>))

#3


我觉得可以重构这个方法。
我觉得之所以微软这样安排ref和默认值是有道理的
ref是既可以in数据又可以out数据,作为一个输出参数来说是不可以默认值的,既然想要让这个参数带有默认值说明这是一个输入参数。
其实可以把参数拆开来用,比如用一个in参数+一个out参数来代替楼主说的情况。
比如可以改成,
void function(int arg1 = 0, out int arg2)
 {
     int iArg = arg1;
     //用iArg进行一系列计算
      ...
      arg2 = iArg;
 }

#4


任何 ref 参数在方法调用前都必须赋值,所以没有为 ref 参数指定默认值的必要

void function(ref int arg)
{
}

unsafe void function(int *arg = null)
{
}

这两个本质的差别是,第一个方法体中,直接操作 arg 绑定的对象,第二个方法体中,必须对 arg 解引用,语义类似于普通托管代码里的引用变量。如果第二种方式对你的程序是可接受的,那么我觉得下面的写法也是可以接受的:

void function(XxxArg arg = null)
{
}

#5


引用 楼主 snser 的回复:
1、如果采用ref的话就不能指定默认值:
void function(ref int arg)
{
}
这里无法指定 ref int arg = 0


你不知道在.net平台下采用ref int比采用int参数要慢么?

闲的没事不要照抄c语言那一套。这是.net,不是c++啊!

#6


如果你一定要使用ref,编译器特意要检查只有已经赋值了的变量才能作为参数。你还要再搞另一套默认值?

#7


引用 2 楼 caozhy 的回复:
不过你可以写一个reference type wrapper代替ref
class RefParam<T>
{
    public T Value { get; set; }
    public RefParam(T value) { Value = value; }
}

void function(RefParam<int> arg = defaul……

谢谢~
正在研究中……

#8


引用 3 楼 xiaoshisanlang1st 的回复:
我觉得可以重构这个方法。
我觉得之所以微软这样安排ref和默认值是有道理的
ref是既可以in数据又可以out数据,作为一个输出参数来说是不可以默认值的,既然想要让这个参数带有默认值说明这是一个输入参数。
其实可以把参数拆开来用,比如用一个in参数+一个out参数来代替楼主说的情况。
比如可以改成,
void function(int arg1 = 0, out……

这样的话 out 还是不能赋予默认值啊
有时候调用function的时候想直接用默认参数而不是指定参数。

#9


引用 6 楼 sp1234 的回复:
如果你一定要使用ref,编译器特意要检查只有已经赋值了的变量才能作为参数。你还要再搞另一套默认值?

首先,感谢你的回答。
我不是一定要用ref啊
只是按照目前的需求首先想到了这个而已,但是ref显然不能满足需求。
至于c++或者C#,我是想在c#里找到类似的比较方便的实现形式。

#10


额,net4不是就已经有了可选参数的设定吗?而可选参数就是一个可以赋初值的玩意

#1


在C#语言层面上无解。

#2


不过你可以写一个reference type wrapper代替ref
class RefParam<T>
{
    public T Value { get; set; }
    public RefParam(T value) { Value = value; }
}

void function(RefParam<int> arg = default(RefParam<int>))

#3


我觉得可以重构这个方法。
我觉得之所以微软这样安排ref和默认值是有道理的
ref是既可以in数据又可以out数据,作为一个输出参数来说是不可以默认值的,既然想要让这个参数带有默认值说明这是一个输入参数。
其实可以把参数拆开来用,比如用一个in参数+一个out参数来代替楼主说的情况。
比如可以改成,
void function(int arg1 = 0, out int arg2)
 {
     int iArg = arg1;
     //用iArg进行一系列计算
      ...
      arg2 = iArg;
 }

#4


任何 ref 参数在方法调用前都必须赋值,所以没有为 ref 参数指定默认值的必要

void function(ref int arg)
{
}

unsafe void function(int *arg = null)
{
}

这两个本质的差别是,第一个方法体中,直接操作 arg 绑定的对象,第二个方法体中,必须对 arg 解引用,语义类似于普通托管代码里的引用变量。如果第二种方式对你的程序是可接受的,那么我觉得下面的写法也是可以接受的:

void function(XxxArg arg = null)
{
}

#5


引用 楼主 snser 的回复:
1、如果采用ref的话就不能指定默认值:
void function(ref int arg)
{
}
这里无法指定 ref int arg = 0


你不知道在.net平台下采用ref int比采用int参数要慢么?

闲的没事不要照抄c语言那一套。这是.net,不是c++啊!

#6


如果你一定要使用ref,编译器特意要检查只有已经赋值了的变量才能作为参数。你还要再搞另一套默认值?

#7


引用 2 楼 caozhy 的回复:
不过你可以写一个reference type wrapper代替ref
class RefParam<T>
{
    public T Value { get; set; }
    public RefParam(T value) { Value = value; }
}

void function(RefParam<int> arg = defaul……

谢谢~
正在研究中……

#8


引用 3 楼 xiaoshisanlang1st 的回复:
我觉得可以重构这个方法。
我觉得之所以微软这样安排ref和默认值是有道理的
ref是既可以in数据又可以out数据,作为一个输出参数来说是不可以默认值的,既然想要让这个参数带有默认值说明这是一个输入参数。
其实可以把参数拆开来用,比如用一个in参数+一个out参数来代替楼主说的情况。
比如可以改成,
void function(int arg1 = 0, out……

这样的话 out 还是不能赋予默认值啊
有时候调用function的时候想直接用默认参数而不是指定参数。

#9


引用 6 楼 sp1234 的回复:
如果你一定要使用ref,编译器特意要检查只有已经赋值了的变量才能作为参数。你还要再搞另一套默认值?

首先,感谢你的回答。
我不是一定要用ref啊
只是按照目前的需求首先想到了这个而已,但是ref显然不能满足需求。
至于c++或者C#,我是想在c#里找到类似的比较方便的实现形式。

#10


额,net4不是就已经有了可选参数的设定吗?而可选参数就是一个可以赋初值的玩意