Подтвердить что ты не робот

Можно ли использовать типы ссылок в С# встроенный Action <> delegate?

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

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

Будет компилироваться. Но если я использую Action<>, он не будет компилироваться:

public event Action< ref Guid > ETest;

Любые подсказки?

4b9b3361

Ответ 1

Нет, вы не можете использовать pass-by-reference с делегатами Action. Хотя в структуре существует понятие "тип, переданный по ссылке" как Type, это не действительно тип в нормальном смысле, что касается С#. 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);

Ответ 2

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

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

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 не изменяется, данные сохраняются.

Также размещен в моем блоге.