Не удается получить первое имя метода в многоадресном делегате - PullRequest
4 голосов
/ 14 января 2012

У меня есть этот код:

public void AddMenuRow(FuncInvoker i_FuncToAdd)   //  add a row to menu.
{
    if (d_Lines == null)
    {
        d_Lines = new FuncInvoker(i_FuncToAdd);
    }
    else
    {
        d_Lines += i_FuncToAdd;
    }
}

для добавления методов в список вызовов.

А теперь я хочу напечатать название каждого метода на консоли, поэтому я сделал это:

public void Show()
{
    int count = 1;
    string name = null;

    Console.WriteLine(m_Title);
    foreach (FuncInvoker list in d_Lines.GetInvocationList())
    {
        name = list.Method.Name;
        Console.WriteLine((count++) + ". " + name);
    }
}   

Проблема заключается в первом имени метода, которое всегда выводит «invoke» по какой-то причине. Следующие методы в ссылке делегата работают нормально.

Может ли кто-нибудь помочь мне с этим? Я перепробовал все.

1 Ответ

5 голосов
/ 14 января 2012

В этой строке:

d_Lines = new FuncInvoker(i_FuncToAdd);

... вы на самом деле создаете новый экземпляр делегата, который оборачивает исходный делегат. Метод-цель этого нового делегата будет Invoke методом исходного делегата (при условии, что он одноадресный), который объясняет поведение, которое вы наблюдаете.

Очевидный обходной путь - не использовать оболочку, а просто скопировать ссылку на исходный делегат в переменную:

d_Lines = i_FuncToAdd;

Но вы могли бы также полностью отказаться от ветки 'special-case' и просто сделать (при условии, что аргумент не может быть null):

public void AddMenuRow(FuncInvoker i_FuncToAdd)                    
{
    d_Lines += i_FuncToAdd;
}

Это будет работать нормально, так как Delegate.Combine (то есть синтаксис +=) предназначен для возврата ссылки на второй делегат, если первый делегат равен null, вместо броска исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...