Делегировать с параметром ref, который может иметь значение null - PullRequest
0 голосов
/ 15 июля 2011

Это смешно, я знаю ... Но вот демо:

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' в ноль в обработчике событий, но я не могу передать ноль какссылкаЯ попробовал это вместо этого:

    public delegate void FooHandler(object sender, ref Foo? f);

Но Foo обнуляем, так что это не работает.Затем я попытался изменить метод invoke для обработчика и настроить фиктивный нулевой элемент для передачи, который тоже не работал.Я попытался использовать вместо ref, так как out не нуждается в инициализированной переменной, и она скомпилирована, но не запустилась.

Это действительно странно, и я никогда не видел ничего подобного.Я мог бы изменить класс Foo на ненулевой, чтобы я мог реализовать его как Nullable, или я мог бы добавить свой собственный флаг Foo.HasValue и сделать это таким образом ... Но нет способа сделать это без изменения класса Foo

Ответы [ 2 ]

4 голосов
/ 15 июля 2011

В 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);

То же самое относится к делегатам / событиям.

3 голосов
/ 15 июля 2011

Это может определенно работать, хотя и весьма не идиоматично ... вы говорите, что попробовали и потерпели неудачу, но без кода мы не узнаем, что вы сделали неправильно.

Игнорирование части события и первого параметра, оба из которых не имеют значения, вот полный пример, показывающий, что оба параметра 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

    }
}
...