2012-11-23 7 views
9

Jestem nowy w stosunku do leków generycznych i mam problem z zaimplementowaniem małego kodu do samodzielnej nauki.Jak rzutować wartość typu int na typowy parametr, który jest równoważny, taki jak char?

Tworzę listę połączoną. Chcę, aby przechowywał wartości char lub int. Więc postanowiłem zrobić realizację Generic:

public class Node<T> where T : struct, IConvertible 
{ 
    public Node<T> next = null; 
    public T data = default(T); 

    public Node(T value) { this.data = value; } 
} 

Mam metodę, która tworzy połączoną listę według generowania losowych wartości w przedziale [33,127) przeliczania wartości z typem określonym przez T (np jeśli 86 jest generowane, a T to Char, wówczas wartość do zapisania w węźle z listą połączeń będzie wynosić "V", a jeśli T to Int32, to po prostu będzie to wartość 86). Ja skierowane dwa problemy:

static Node<IConvertible> CreateList<T>(int len) where T : struct, IConvertible 
    { 
     Random r = new Random((int)DateTime.Now.Ticks); 
     T value = (T)r.Next(33, 127);  // Problem #1 

     Node<T> head = new Node<T>(value); 
     Node<T> n = head; 

     for (int i = 1; i < len; i++) 
     { 
      n.next = new Node<T>(value); 
      n = n.next; 
     } 
     return head; // Problem #2 
    } 

Są to problemy:

1), zwykle jest to możliwe (int) = wartość (znaki) r.Next (33, 127). Dlaczego, jeśli T jest typu Char, kompilator mówi "Nie można przekonwertować typu" int "na" T ", nawet gdybym określił" where T: struct, IConvertible "?

2) „Nie można niejawnie przekonwertować typu«LinkedList.Node<T>»do«LinkedList.Node<System.IConvertible>»” Jeśli T jest albo Int32 lub Char i oboje wdrożyć IConvertible, co jest sposobem, aby rzucić Node<Int32> lub Node<Char> do Node<IConvertible>?

Wielkie dzięki!

Odpowiedz

1

Zastosowanie

T value = (T)Convert.ChangeType(r.Next(33, 127), typeof(T)); 
2

Korzystanie z Random wygenerować jakieś dane to rodzaj sprzeczności z użyciem leków generycznych. Chciałbym oddzielić dwa podobnego tak:

static Node<T> CreateList<T>(int len, Func<T> dataProvider) where T : struct, IConvertible 
{ 
    Node<T> head = new Node<T>(dataProvider()); 
    Node<T> n = head; 

    for (int i = 1; i < len; i++) 
    { 
     n.next = new Node<T>(dataProvider()); 
     n = n.next; 
    } 
    return head; 
} 

Telefoniczny kod:

Random r = new Random(); 
Node<char> list = CreateList(10,() => (char)r.Next(33, 127)); 

Druga sprawa to Node<IConvertible> nie jest dozwolony przez struct przymusu na Node<T>. Po prostu zwróć Node<T>. Nawet jeśli usuniesz ograniczenie z Node<T>, nie będzie możliwe zwrócenie Node<IConvertible>, ponieważ klasy ogólne nie obsługują wariancji.

6

Problem polega na tym, że T może być dowolną strukturą, np. Guid, SByte ... lub custom-new-one. i choć możemy być pewni, że T jest struct i IConvertible, tam nie musi być jawne operator oddanych do

public static explicit operator AnyStruct(int i) 

Druga kwestia do odlewania Node<System.IConvertible>Node<System.IConvertible> zwykle. Żadnej listy List<T> nie można przekonwertować na List<System.IConvertible>.

Potrzebujemy deklaracji kowariancji na interfejsie: INode<out T>. Następnie można przekształcić INode<T> w INode<System.IConvertible>

Powiązane problemy