2010-06-11 17 views
6

Biorąc zespół, który zawieraTworzenie delegata za pomocą refleksji

namespace Foo{public class Bar;} 

Jak mogę utworzyć Action<Foo.Bar> z innego zespołu, bez odwoływania się do pierwszego zespołu w czasie kompilacji?

+1

Co masz na myśli przez „bez odwoływania się do pierwszego zespołu”? Jeśli chcesz użyć typu z tego zespołu, musisz go w jakiś sposób odwołać. – LukeH

+0

Przykro mi, to znaczy bez dodawania go jako odniesienia do projektu Visual Studio. tj. użyj Assembly.LoadFrom(), aby załadować go tak, aby nie było żadnych zależności w czasie kompilacji. – dss539

+0

@LukeH - Edytowane pytanie jest nieco bardziej przejrzyste. Dzięki za wejście. – dss539

Odpowiedz

10

Jeśli używasz

Type barType = Type.GetType("Foo.Bar, whateverassembly"); 
Type actionType = typeof(Action<>).MakeGenericType(barType); 

actionType będzie teraz reprezentować Action<Foo.Bar>. Jednak aby go użyć, musisz rozważyć użycie refleksji, więc musisz znaleźć numer MethodInfo, który pasuje do podpisu void(Foo.Bar) i zadzwonić pod numer Delegate.CreateDelegate, aby utworzyć delegata. Będziesz potrzebował Delegate.DynamicInvoke, aby go uruchomić.

Delegate call = Delegate.CreateDelegate(actionType, ...); 
... 
call.DynamicInvoke(someBar); 

Coś mi mówi, że nie to, co myślisz o ...

+0

Co powinienem umieścić w '...' w 'Delegate.CreateDelegate (actionType, ...);'? Myślę, że twoje rozwiązanie jest tym, czego potrzebuję, ponieważ i tak będę przekazywał tego delegata do konstruktora w zespole źródłowym. – dss539

+0

Dzięki, rozwiązałem moje problemy. Twoja pomoc jest bardzo ceniona. – dss539

3

Nie można go nazwać Action<Foo.Bar> w kodzie wywołującym, ponieważ nie będzie dostępu do definicji tego typu, jeśli nie odwołasz się do niego podczas kompilacji. Ponieważ Delegaci są przeciwstawne, możesz zwrócić Action<Object> i użyć tego lub użyć Action<IBar>, gdzie interfejs IBar jest zdefiniowany w zespole referencyjnym i zaimplementowany przez Foo.Bar.

Jeśli nie zwróci Action<Object>, to albo trzeba użyć Foo.Bar członków za pośrednictwem refleksji (lub dynamic jeśli przy użyciu C# 4.0) lub skorzystać oddanych do Foo.Bar gdzie kod odlew ma odniesienie do zespołu, gdzie Foo.Bar jest zdefiniowana .

+0

"Nie można tego nazwać Akcja w kodzie wywołującym" - tak, zdaję sobie z tego sprawę. Odp: contravariance - Niestety nie określiłem .NET 3.5. Naprawię tagi. – dss539

Powiązane problemy