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 の場合、値はリンク リストに格納されます)。 node は 'V' になります。T が Int32 の場合、値は単純に 86 になります)。私は2つの問題に直面しています:

    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 型の場合、「where T : struct, IConvertible」を指定したにもかかわらず、コンパイラは「型 'int' を 'T' に変換できません」と言うのはなぜですか?

LinkedList.Node<T>2) 「型 ' ' を ' ' に暗黙的に変換できません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)

2番目の問題のキャスト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てデータを生成することは、ジェネリックを使用することとは少し異なります。私は次のように2つを分離します:

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

2 番目の問題は、に対する制約Node<IConvertible>によって許可されていません。を返すだけです。から制約を削除しても、ジェネリック クラスはバリアンスをサポートしていないため、 a を返すことはできません。structNode<T>Node<T>structNode<T>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 に答える