2016-02-17 10 views
6

chciałbym napisać następującą metodęJak uczynić metoda rodzajowa, które mają ogólny typ

private void Foo<T, TItem>(T<TItem> param1) 

Gdzie T musi być typem generycznym trwa TItem jako rodzajowy informacji.

przykładem połączenia byłoby jak:

private void Main() 
{ 
    List<int> ints = new List<int>(); 
    Foo<List, int>(ints);  
} 

Edit: w moim przypadku będę potrzebował tylko dla zbiorów. Rzeczywistym przypadkiem użycia jest to, że chciałem napisać metodę, która dodaje coś do ICollection, niestety ICollection nie ma metody .Add, którą ma tylko ICollection<T>.

nie mogę zmienić metodę:

private Foo<T>(ICollection<T>) 

ponieważ z tym tracę informacje jaki typ rzeczywisty liście to, co jest dla mnie ważniejsze niż to, co wpisać pozycje na liście.

więc narodził się powyższy pomysł, który nie zadziałał.

+0

Nie sądzę, że to możliwe, biorąc pod uwagę, że 'List' zawsze oczekuje parametru rodzajowego. – MutantNinjaCodeMonkey

+1

Nie sądzę, że można zrobić to ograniczenie. A co z tym, że T jest typem generycznym, który implementuje IInterface , gdzie T pochodzi od TItem? –

+0

Naprawdę nie rozumiem, w jaki sposób 'Foo' wymagał by' T' i 'TItem' były powiązane w opisany sposób; czy mógłbyś podać bardziej konkretny przykład? – Codor

Odpowiedz

7

Skoro trzeba, że ​​tylko w kolekcjach, można opisać metodę tak:

private void Foo<T, TItem>(T param1) 
    where T: ICollection<TItem> 
{ 
} 

Jednak w tym przypadku należy podać konkretny typ rodzajowy (List<int>) jako pierwszego parametru rodzajowego, nie możesz używać tylko List:

List<int> ints = new List<int>(); 
Foo<List<int>, int>(ints); 
+0

'' IEnumerable ''? –

+0

@EhsanSajjad Od 'ICollection ' implementuje 'IEnumerable ' mógłbyś użyć jednego lub innego, który zależy od wymagań – dotnetom

+0

To rozwiązanie wydaje się działać, ale to trochę śmierdzi, że muszę podać typową informację o typie, czy jest może jakiś obejść to? –

0

Wydaje mi się, jesteś w pułapce umysłu. Prawdopodobnie istnieje lepszy sposób na rozwiązanie tego, co próbujesz zrobić.

W każdym razie spróbuj użyć Dictionary. Nie musisz właściwie pisać metody.

int number = 15; 
double dub = 15.5; 
Button button = new Button(); 

Dictionary<object, Type> typeGlossary = new Dictionary<object, Type>(); 
typeGlossary.Add(number, typeof(int)); 
typeGlossary.Add(dub, typeof(double)); 
typeGlossary.Add(button, typeof(Button)); 

W końcu twój wstrząśnięty, wstrząśnięty, kodowany mózg przestanie próbować odeprzeć mocno napisany system C#. Wszyscy to robimy w pewnym momencie.

1

Może to pomoże:

Utwórz klasę podstawową i klasę pochodną.

public class Item 
{ 

} 

public class Item<T> : Item 
{ 
    T Value; 

    public Item(T value) 
    { 
     Value = value; 
    } 
} 

Następnie można go używać jak chcesz:

public class SomewhereElse 
{ 
    public void Main() 
    { 
     List<Item> itemCollection = new List<Item>(); 
     itemCollection.Add(new Item<int>(15)); 
     itemCollection.Add(new Item<string>("text")); 
     itemCollection.Add(new Item<Type>(typeof(Image))); 
     itemCollection.Add(new Item<Exception>(new StackOverflowException())); 
     itemCollection.Add(new Item<FormWindowState>(FormWindowState.Maximized)); 
     // You get the point.. 
    } 
} 
Powiązane problemy