2011-07-14 4 views
0

Это смешно, я знаю ... Но Heres демо:делегат с обнуляемого параметром реф, который может быть пустым

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 как ref. Я попробовал это вместо этого:

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

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

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

+0

Общая схема событие 'FooHandler (объект отправителя, EventArgs e) '. Что вы пытаетесь решить, изменив этот шаблон и установив аргументы arg в null? – ChrisWue

+0

Это может абсолютно работать, но вы не предоставили нам полный код для любого из параметров, которые вы пробовали. Я отправлю * рабочий * пример, но, конечно, это не покажет, какая разница ... –

+0

Классы по определению являются ссылочными типами и, следовательно, уже обнуляются, поэтому нет смысла обертывать их нулевым типом , Конструкция 'Nullable ' предназначена для предоставления типов значений (которые по определению не равны нулю) для представления нулевого значения. –

ответ

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 

    } 
} 
+0

Вы правы, мне следовало бы написать больше кода, но я представил себе теоретическую проблему, а не ошибку кодирования.Оказывается, это была плохая ошибка, так как это была ошибка кодирования, когда я получал отдельную нулевую ссылку в той же строке и предположил, что это параметр. – Matt

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

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

Смежные вопросы