带有可为空的ref参数的委托,该参数可能为空
本文关键字:参数 ref | 更新日期: 2023-09-27 18:02:02
我知道这很荒谬…但这里有一个演示:
class Foo
{
// A lot of data in the nullable class foo.
}
class bar
{
public delegate void FooHandler(object sender, ref Foo f);
public event FooHandler FooChanged;
}
问题是我想在事件处理程序中将'f'设置为null,但我不能将null作为ref传递。我尝试了这个:
public delegate void FooHandler(object sender, ref Foo? f);
但是Foo是可空的,所以这不起作用。然后,我尝试修改处理程序的invoke方法,并设置要传递的虚拟空项,这也不起作用。我尝试使用out代替ref, out不需要初始化变量,并且编译但没有运行。
这真的很奇怪,我从来没有见过这样的事情。我可以将Foo类更改为非空的,这样我就可以将其实现为空,或者我可以添加自己的标志Foo。HasValue和这样做…但是没有办法在不改变Foo类的情况下做到这一点吗?在c#中,如果没有对变量的实际引用,则不可能调用带有ref
参数的方法。
例如,如果你有一个方法
void DoWork(ref Foo foo)
{
foo = new Foo();
}
你可以做
Foo foo = null;
DoWork(ref foo); // works
但是你不能做
DoWork(ref null); // does not compile
DoWork(null); // does not compile
如果您想使ref
参数成为可选的,您必须提供两个重载:
void DoWork();
void DoWork(ref Foo x);
这绝对可以工作,尽管它非常不习惯…你说你已经试过了,但是失败了,但是没有代码,我们就不知道你做错了什么。
忽略事件部分和第一个参数,这两个都是不相关的,这里有一个完整的示例,显示out
和ref
参数都工作得很好:
using System;
delegate void ByRef(ref string x);
delegate void ByOut(out string x);
class Test
{
static void Main()
{
ByRef r = (ref string x) => { x = null; };
string tmp = "Not null";
r(ref tmp);
Console.WriteLine(tmp == null); // True
ByOut o = (out string x) => { x = null; };
string tmp2;
o(out tmp2);
Console.WriteLine(tmp2 == null); // True
}
}