Как мне создать класс значений CLI, содержащий список (или аналогичный), который передается по значению?

StackOverflow https://stackoverflow.com/questions/2085337

Вопрос

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

struct Params
{
    // values...
}

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

    // values...
}

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

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

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

    // values...
}

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

Это было полезно?

Решение

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

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

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

Другие советы

Я не думаю, что вы можете передавать свой класс настроек по значению, потому что "типы значений не могут содержать определенные пользователем специальные функции-члены" (из 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 # вы бы тогда имели:

Settings s1, s2;
// ... some code modifying s1
s2 = (Settings)s1.Clone();

который почти так же чист, как Settings settings1 = settings2; синтаксис стиля вы получаете с помощью передачи по значению.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top