2010-12-29 3 views
1

Есть ли способ сделать это:Как создать общий метод с общим в предложении 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

«Генерал-сумасшествие» дает какое-либо представление о вопросе? Как вы планируете привлекать хорошие ответы? Как последующие поисковики найдут этот вопрос, когда столкнутся с подобной проблемой? Постарайтесь использовать осмысленные вопросы так же, как вам хотелось бы иметь в своем коде значимые имена классов и методов. –

+0

Я обычно более ясен. Это сложная ситуация. Как бы вы сформулировали вопрос? :) – Jordan

+0

Не сказал, что это было легко! Начните с «множественного вывода параметров типового типа» и работайте оттуда. –

ответ

2

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

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

+0

+1 PS Я думаю, что OP думал, что 'TPayload' может быть выведен из' TEvent' из-за ограничения 'where', но это не часть фаз вывода типа C#. –

+0

OP (a.k.a. me) действительно подумал. Мне нужно создать метод, который принимает любое составное событие. Я не могу использовать «EventBase», потому что у него нет метода «Подписаться», который в первую очередь является всей точкой метода. – Jordan

0

Верьте или нет, 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 

Выход:

 
A 
B 
C 
0 

К сожалению, as Mehrdad has indicated, это невозможно в C#.

+0

Что можно сделать в C#? У нас есть методы расширения. Из того, что я видел, C# и VB на 90% функционально одинаковы. Наш синтаксис просто немного неясен (шутит - бывший VB'er). Не решает мою проблему. Я думаю, что моя проблема в том, что я пытаюсь сделать generics слишком универсальными. Аргументы типа должны быть конкретными. – Jordan

+0

@Jordan: В C# вы не можете определить общий метод расширения с параметрами * two * generic type и вывести один из них. Обратите внимание на метод «Добавить» из моего примера, он определяется двумя параметрами типа, но вызывается только одним. У C# этого нет - это то, что я пытался передать, хотя, возможно, я не занимался самой большой работой. –

+0

@ Джордан: И ты прав, он все равно не ответил бы на ваш вопрос. Это был скорее «интересный/несколько уместный лакомый кусочек, чтобы знать» ответ (я имею в виду, это все-таки VB ...). –