Можно ли использовать типы ссылок в C # встроенном делегате Action <>? - PullRequest
23 голосов
/ 10 ноября 2009

C # имеет встроенных делегатов Action<> и Func<>. Можно ли использовать параметры типа 'ref' для этих делегатов? Например, этот код:

public delegate void DTest( ref Guid a );
public event DTest ETest;

Скомпилирует. Но если я использую Action<>, он не скомпилируется:

public event Action< ref Guid > ETest;

Есть подсказки?

Ответы [ 2 ]

39 голосов
/ 10 ноября 2009

Нет, вы не можете использовать передачу по ссылке с делегатами Action. Хотя в рамках фреймворка существует понятие «тип, переданный по ссылке» как Type, на самом деле это не тип в обычном смысле, как в C #. ref - это модификатор параметра, а не часть имени типа, если вы понимаете, о чем я.

Однако вы можете создать свой собственный набор эквивалентных типов, например,

delegate void ActionRef<T>(ref T item);

Конечно, если вам нужно сочетание параметров ref и non-ref в одном делегате, вы получите ужасный набор комбинаций:

delegate void ActionRef1<T1, T2>(ref T1 arg1, T2 arg2);
delegate void ActionRef2<T1, T2>(T1 arg1, ref T2 arg2);
delegate void ActionRef3<T1, T2>(ref T1 arg1, ref T2 arg2);
8 голосов
/ 27 октября 2011

Вы можете, если ваша ссылка является сложным объектом (имеет свойства).

Пример объекта:

public class MyComplexObject
{
    /// <summary>
    /// Name provided for the result.
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Value of the result.
    /// </summary>
    public object Value { get; set; }
}

Используется в действии:

Action<MyComplexObject> myAction = (MyComplexObject result) =>
{
    result.Value = MyMethodThatReturnsSomething();                                              
};

Поскольку ссылка MyComplexObject не изменяется, данные сохраняются.

Также опубликовано в моем блоге .

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