2012-11-23 13 views
9

Ich bin neu bei Generika und habe Probleme, einen kleinen Self-Practice-Code zu implementieren.Wie kann ich einen int-Wert in einen generischen Typparameter umwandeln, der äquivalent ist wie char?

Ich erstelle eine verknüpfte Liste. Ich möchte, dass es char oder int-Werte speichert. Also habe ich beschlossen, die Umsetzung zu machen 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; } 
} 

Ich habe eine Methode, die die verknüpfte Liste erstellt durch zufällige Werte im Bereich Erzeugung [33.127), den Wert in den Typ Umwandlung von T angegeben (zB wenn 86 erzeugt und T ist Char, dann ist der Wert, der in dem Knoten der verknüpften Liste gespeichert werden soll, "V"; Wenn T Int32 ist, dann wird der Wert einfach 86). Ich bin vor zwei Probleme:

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 
    } 

Dies sind die Probleme:

1) Normalerweise ist dies möglich: (int) value = (char) r.Next (33, 127). Warum, wenn T vom Typ Char ist, sagt der Compiler "Kann den Typ 'int' nicht in 'T' konvertieren, selbst wenn ich" where T: struct, IConvertible "angegeben hätte?

2) „kann nicht implizit Typ konvertieren‚LinkedList.Node<T>‘auf‚LinkedList.Node<System.IConvertible>‘“ Wenn T entweder Int32 oder Char und beide IConvertible implementieren, was die Art und Weise Node<Int32> oder Node<Char>-Node<IConvertible> zu werfen?

Vielen Dank!

Antwort

1

Verwenden

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

Ihre Nutzung von Random einige Daten zu erzeugen, ist eine Art uneins mit Verwendung von Generika. Ich würde trennt die beide in etwa so:

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; 
} 

Telefonvorwahl:

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

Das zweite Problem ist Node<IConvertible> wird von Ihrer struct Einschränkung auf Node<T> nicht erlaubt. Gib einfach eine Node<T> zurück. Selbst wenn Sie die struct-Einschränkung von Node<T> entfernen, ist es nicht möglich, Node<IConvertible> zurückzugeben, da generische Klassen die Varianz nicht unterstützen.

6

Das Problem ist, dass T jede Struktur sein könnte, z.B. Guid, SByte ... oder custom-new-one. und während wir sicher sein können, dass T ist struct und IConvertible, es muss nicht explizit Cast-Operator sein

public static explicit operator AnyStruct(int i) 

Die zweite Ausgabe Gießen Node<System.IConvertible>-Node<System.IConvertible> üblich ist. Jede Liste List<T> kann nicht in List<System.IConvertible> konvertiert werden.

Was wir brauchen, ist Kovarianz-Deklaration an der Schnittstelle: INode<out T>. Dann könnte die INode<T> in INode<System.IConvertible>

umgewandelt werden
Verwandte Themen