Коллекция .NET, которая является структурой - PullRequest
2 голосов
/ 17 декабря 2010

Вот интересный вопрос ... есть ли коллекция, которая является структурой где-то в .net framework?

Просто для пояснения, все существующие коллекции (список, массив и т. Д.) Являются ссылочными типами ... даже если для общего параметра задан тип значения. Но я хочу знать, есть ли способ сделать коллекцию, которая на самом деле является структурой. Я, очевидно, не планировал бы обойти это (что привело бы к тонне копирования) ... Я бы оставил это как приватный член в своем классе (внутреннее состояние), так что это определяется только один раз. Идея состоит в том, что я смогу избежать вызова сборщика мусора просто для того, чтобы сделать небольшую коллекцию (вспомним XNA).

Если предположить, что человека не существует, второстепенная часть вопроса состоит в том, какова была бы идеальная структура данных для этого. связанный список?

Ответы [ 2 ]

8 голосов
/ 17 декабря 2010

Нет, такого типа не существует, и это не будет хорошей идеей. Структуры должны быть небольшими неизменяемыми типами значений в соответствии с рекомендациями Microsoft.

Из Рекомендации по использованию типа значения :

  • Действуй как примитивные типы.
  • Размер экземпляра не должен превышать 16 байт.
  • Неизменны.
  • Семантика значений желательна.

Было бы трудно реализовать связанный список как тип значения, поскольку связанные списки обычно определяются рекурсивно. Это отлично работает:

class Node<T>
{
    public T Value;
    public Node<T> Next;
}

Но это не так, потому что структуры имеют фиксированный размер, и этот размер должен быть известен при определении структуры:

struct Node<T>
{
    public T Value;

    // Error: Struct member 'Node<T>.Next' of type 'Node<T>'
    // causes a cycle in the struct layout
    public Node<T> Next; 
}
4 голосов
/ 17 декабря 2010

На самом деле существует структура, которая является коллекцией. BitVector32 является структурой и действует как набор из 32 логических значений, или 4 байта, или 2 шорт. Это очень удобно, когда вы хотите заняться биткойлингом, но не хотите слишком много думать о создании масок и тому подобного.

Также, если вы действительно планируете развернуть свой собственный, имейте в виду, что если вы заставите его реализовать что-то вроде IList<Int32>, вы никогда не должны отправлять его в код, который читается как

public static void SomeMethod(IList<Int32> list)
{
       ....
}

Поскольку это будет боксировать, и каждый доступ к элементу, скорее всего, приведет к боксу, вместо этого отправьте его методу, который имеет эту подпись: *

public static void SomeMethod<T>(T list) where T:IList<Int32>
{
       ....
}

В качестве второго примера перед каждым callvirt будет выдаваться код операции constrained, что позволит избежать блокирования при вызове членов структуры. Удачи все же.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...