2016-01-12 22 views
5

Mam przeczucie, że nie patrzę na tę kwestię pod właściwym kątem, a ja po prostu nie myślę o innym rozwiązaniu.Wywołanie metody ogólnej/delegata z nietypowej klasy bazowej

Przyjmując tę ​​klasę ogólną;

public abstract class Port<T> 
{ 
    public delegate T PullDelegate(); 

    private PullDelegate pull; 

    public Port(PullDelegate pull) 
    { 
     this.pull = pull; 
    } 

    public T Pull() 
    { 
     return pull(); 
    } 
} 

Służy do definiowania "portów" w edytorze węzłów grafów. Port może przenosić obiekt/wartość z jednego węzła do drugiego, ale musi również być "bezpieczny pod względem typu", co oznacza, że ​​nie mogę podłączyć żadnego portu do innego niewłaściwego typu (przynajmniej nie bez jakiejś konwersji).

Węzeł "posiada" port i przekazuje go do jednej ze swoich metod, więc gdy inny węzeł "ściąga" wartość, port po prostu wywołuje go i zwraca poprawną wartość.

Mój problem zaczyna się, gdy próbuję zadzwonić pod numer Pull() z nietypowej kolekcji. Oczywiście mogłem zrobić nietypową metodę bazową, ale wtedy Pull nie mógł zwrócić T, musiałby zwrócić object.

Ponadto, każdy węzeł ma akcesory do kolekcjonowania dla swoich portów, więc inne elementy mogą je uzyskać. To zbieranie musi być nietypowe, ponieważ węzeł może mieć wiele portów wielu typów.

public abstract Port[] Inputs { get; } 
    public abstract Port[] Outputs { get; } 
    public abstract Port[] Entries { get; } 
    public abstract Port[] Exits { get; } 

W momencie, gdy typ nietypowy wchodzi w grę, wszystko, co ogólne, staje się niedostępne. Gdyby tylko Port<>[] byłaby rzeczą.

czuję jakbym czegoś brakuje ...

+1

Można utworzyć 'IPort {T Pull(); } 'następnie stwórz' IEnumerable > '. – Lee

+0

Co z twoimi obiektami zaimplementowałoby jeden interfejs, abyś mógł być pewien, że to przynajmniej będzie i obiekt, który to implementuje, czy to by zmieniło twoją sytuację? Można więc uniknąć używania obiektów, ale raczej coś takiego jak IMyObject. –

+0

Czy klasa "Port" klasy 'Port '? Jak dokładnie chcesz używać kolekcji non ogólnej? –

Odpowiedz

1

Bądź Port<T> implementować interfejs nierodzajową IPort poprzez określone implementacje. W ten sposób jest ukryty przed API, ale nadal pozwala na wywoływanie metod w klasach ogólnych.

public interface IPort 
{ 
    object SomeAction(object data); 
} 

public class Port<T> : IPort 
{ 
    //[.. all other methods ..] 


    object IPort.SomeAction(object data) 
    { 
     var typedData = (T)data; 
     //invoke our typed version. 
     return SomeAction(data); 
    } 

    public T SomeAction(T data) 
    { 
     // ... 
    } 
} 
+0

Jeśli moim problemem było po prostu przekazanie czegoś, nie zawracałbym sobie głowy rodzajami generycznymi. Problem, który mam, polega na tym, że dostaję coś z tego. Załóżmy, że 'SomeAction' zwraca' T'. – LightStriker

+0

@LightStriker: A co z zwracaniem obiektu z IPort.SomeAction i T z IPorta .SomeAction (z IPortem implementującym IPort)? Myślę, że to właśnie robią w IEnumerable/IEnumerable . – devstruck

+0

@ LightStriker: Masz na myśli zaktualizowaną odpowiedź? – jgauffin

Powiązane problemy