我知道这很荒谬......但是这是一个演示:
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方法并设置一个虚拟的null项来传递,这也无效。我尝试使用out而不是ref因为out不需要初始化变量,并且编译但是没有运行。
这真的很奇怪,我从来没有见过这样的东西。我可以将Foo类更改为不可为空,这样我就可以将它实现为Nullable,或者我可以添加自己的标志Foo.HasValue并按这样做...但是如果不改变Foo类就没有办法做到这一点?
答案 0 :(得分:4)
在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);
同样适用于代表/活动。
答案 1 :(得分:3)
这可以绝对工作,虽然它非常非惯用...你说你已经尝试过但失败了,但没有代码,我们就不会知道你做错了什么
忽略事件部分和第一个参数,两者都不相关,这是一个完整的示例,显示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
}
}