9

我是泛型的新手,我在实现一个小的自我练习代码时遇到了一些麻烦。

我正在创建一个链接列表。我希望它存储 char 或 int 值。所以我决定使实现通用:

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

我有一个方法通过生成[33,127)范围内的随机值来创建链表,将值转换为T指定的类型(例如,如果生成86并且T是Char,那么要存储在链表中的值节点将是“V”;如果 T 是 Int32,则值将简单地为 86)。我面临两个问题:

    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
    }

这些是问题:

1) 通常这是可能的:(int) value = (char) r.Next(33, 127)。为什么如果 T 是 Char 类型,编译器会说“无法将类型 'int' 转换为 'T'”,即使我指定了“where T : struct, IConvertible”?

2)“不能将类型' LinkedList.Node<T>'隐式转换为' LinkedList.Node<System.IConvertible>'”如果T是Int32或Char并且它们都实现了IConvertible,那么转换或转换的方法Node<Int32>Node<Char>什么Node<IConvertible>

非常感谢!

4

3 回答 3

6

问题是T可以是任何结构,例如 Guid、SByte... 或custom-new-one。虽然我们可以确定Tstructand IConvertible,但不一定要显式转换运算符

public static explicit operator AnyStruct(int i)

Node<System.IConvertible>铸造到的第二个问题Node<System.IConvertible>是通常的。任何列表List<T>都不能转换为List<System.IConvertible>.

我们需要的是 interface: 上的协方差声明INode<out T>。然后INode<T>可以转换为INode<System.IConvertible>

于 2012-11-23T20:37:24.027 回答
2

您使用Random来生成一些数据与使用泛型有些不一致。我会像这样将两者分开:

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

调用代码:

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

第二个问题是Node<IConvertible>structNode<T>. 只需返回一个Node<T>. 即使您确实struct从 中删除了约束Node<T>,也无法返回 a Node<IConvertible>,因为泛型类不支持方差。

于 2012-11-23T20:36:20.423 回答
1

利用

T value = (T)Convert.ChangeType(r.Next(33, 127), typeof(T));
于 2012-11-23T20:24:43.627 回答