Como faço para criar uma classe CLI Value contendo uma lista (ou similar) que é passada pelo valor?

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

Pergunta

Temos uma biblioteca C ++ que usa uma estrutura contendo um vetor STL de estruturas, assim:

struct Params
{
    // values...
}

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

    // values...
}

Estou escrevendo um invólucro da CLI para a biblioteca e quero equivalentes para os tipos de estrutura acima. Eu estava pensando em usar uma lista como equivalente a um vetor, assim:

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

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

    // values...
}

Mas desde a listau003CT> é um tipo de referência, a lista é transmitida por referência e não pelo valor. Existe uma maneira de criar uma classe CLI contendo uma lista (ou similar) que seja passada pelo valor, junto com o restante dos membros?

Foi útil?

Solução

Concordo com a resposta de McDave, que se resume a isso, o que você está pedindo não é suportado.

Estou especulando que seu ponto principal não é conseguir real passa por valor, mas mais para obter o valor comportamento. Imagine System.String. Isso não é realmente um tipo de valor, mas você pode passar as referências com segurança, porque as strings não podem ser modificadas, você só pode fazer novas.

Para obter o mesmo para uma lista, você pode fazer Params uma propriedade do tipo IList<Param>. Ao atribuí -lo, copie o conteúdo em um novo List<Param> e armazenar o IList ponteiro que você recebe ao ligar AsReadOnly(). A partir de agora, o IList aponta para um objeto que não pode ser modificado. Se a estrutura for passada por valor, o ponteiro será copiado, mas tudo bem, porque aponta para algo imutável. Se o seu objeto for transmitido muito, ele também será mais rápido, porque não há necessidade de uma cópia profunda toda vez.

Outras dicas

Eu não acho que você pode passar sua classe de configurações por valor porque "os tipos de valor não podem conter funções de membros especiais definidas pelo usuário" (de C3417) como o construtor de cópias.

Você pode obter um efeito semelhante usando:

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

No seu código C#, você teria:

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

que é quase tão limpo quanto o Settings settings1 = settings2; Sintaxe de estilo que você recebe com o passe por valor.

Que tal List<Params>^% Params; alternativamente List<Params%>^% Params;?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top