Как создать класс значений CLI, содержащий список (или аналогичный), который передается по значению? - PullRequest
4 голосов
/ 18 января 2010

У нас есть библиотека C ++, которая использует структуру, содержащую вектор структур STL, например:

struct Params
{
    // values...
}

struct Settings
{
    std::vector<Params> m_params;

    // values...
}

Я пишу оболочку CLI для библиотеки и хочу эквиваленты для вышеуказанных типов структур. Я думал об использовании List в качестве эквивалента вектора, вот так:

public value struct Params
{
    // values...
}

public value struct Settings
{
    List<Params>^ Params;

    // values...
}

Но поскольку List является ссылочным типом, список передается по ссылке, а не по значению. Есть ли способ создания класса CLI, содержащего список (или аналогичный), который передается по значению вместе с остальными членами?

Ответы [ 3 ]

1 голос
/ 28 февраля 2010

Я согласен с ответом mcdave, который сводится к тому, что то, что вы спрашиваете, не поддерживается.

Я предполагаю, что ваша главная мысль не в том, чтобы получить фактическое значение передачи, а в большей степени, чтобы получить значение поведение . Подумайте о System.String. На самом деле это не тип значения, но вы можете безопасно передавать ссылки, потому что строки нельзя изменить, вы можете создавать только новые.

Чтобы получить то же самое для списка, вы можете сделать Params свойством типа IList<Param>. При назначении скопируйте содержимое в новый List<Param> и сохраните указатель IList, полученный при вызове AsReadOnly(). Отныне IList указывает на объект, который нельзя изменить. Если структура передается по значению, указатель будет скопирован, но это нормально, поскольку он указывает на что-то неизменное. Если ваш объект много раз передается, он также будет быстрее, потому что нет необходимости в глубокой копии каждый раз.

1 голос
/ 20 января 2010

Я не думаю, что вы можете передавать свой класс Settings по значению, потому что «типы значений не могут содержать определенные пользователем специальные функции-члены» ( из C3417 ), такие как конструктор копирования.

Вы можете добиться аналогичного эффекта, используя:

public value struct Settings : public ICloneable
{
    List<Params>^ m_params;

    virtual Object^ Clone()
    {
        Settings^ rv = gcnew Settings();
        rv->m_params = gcnew List<Params>();
        rv->m_params->AddRange(m_params->ToArray());
        return rv;
    }
}

В вашем коде на C # у вас будет:получить с проходом по значению.

0 голосов
/ 25 января 2010

Как насчет List<Params>^% Params; в качестве альтернативы List<Params%>^% Params;?

...