Как создать универсальный метод с универсальным в предложении where? (Человек, который чист, как грязь!)

Есть ли способ сделать это:

protected void SubscribeToEvent<TEvent, TPayload>(Action<TPayload> a_action)
    where TEvent : CompositePresentationEvent<TPayload>
{
    TEvent newEvent = _eventAggregator.GetEvent<TEvent>();
    SubscriptionToken eventToken = newEvent.Subscribe(a_action);

    _lstEventSubscriptions.Add(new KeyValuePair<EventBase, SubscriptionToken>(newEvent, eventToken));
}

не требуя от пользователя указать TPayload параметр?

2 ответа

Решение

Нет, нет Не в C# 4. Вы не можете сделать это с помощью одного метода.

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

Хотите верьте, хотите нет, но в VB.NET есть что-то похожее для методов расширения.

Скажем, у меня есть следующий метод расширения:

<Extension()>
Function Append(Of TInferred, T)(ByVal source As IEnumerable(Of TInferred)) As Object()
    Dim items As List(Of Object) = source.Cast(Of Object).ToList()

    Dim value As T = Nothing ' equivalent to default(T) '
    items.Add(value)

    Return items.ToArray()
End Function

Тогда я мог бы на самом деле вызвать этот метод, передавая параметр одного типа, для T только с TInferred выводится:

Dim strings = New String() {"A", "B", "C"}

' Notice I am passing only one type argument. '
Dim objects = strings.Append(Of Integer)()

For Each obj As Object In objects
    Console.WriteLine(obj)
Next

Выход:

В
С
0

К сожалению, как отметил Мерадад, это не возможно в C#.

Другие вопросы по тегам