Comment puis-je créer une classe de valeur CLI contenant une liste (ou similaire) qui est passé par valeur?

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

Question

Nous avons une bibliothèque C ++ qui utilise une struct contenant un vecteur STL de struct, comme suit:

struct Params
{
    // values...
}

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

    // values...
}

J'écris une enveloppe CLI pour la bibliothèque, et je veux équivalents pour les types struct ci-dessus. Je pensais à l'aide d'une liste comme l'équivalent d'un vecteur, comme suit:

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

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

    // values...
}

Mais depuis List est un type de référence, la liste est passée autour par référence plutôt que la valeur. Est-il possible de créer une classe de CLI contenant une liste (ou similaire) qui est passé par valeur, ainsi que le reste des membres?

Était-ce utile?

La solution

Je suis d'accord avec la réponse de mcdave, qui se résume à ce que vous demandez est pas pris en charge.

Je suis en train de spéculer que votre point principal est de ne pas obtenir réelle passer par valeur, mais plus pour obtenir le passage par valeur comportement . Pensez à System.String. Ce n'est pas vraiment un type de valeur, mais vous pouvez passer les références en toute sécurité autour parce que les chaînes ne peuvent pas être modifiés, vous ne pouvez en faire de nouveaux.

Pour obtenir la même chose pour une liste, vous pouvez faire Params une propriété de type IList<Param>. Lors de l'attribution, copiez le contenu dans un nouveau List<Param> et stocker le pointeur de IList vous obtenez lorsque vous appelez AsReadOnly(). Désormais, les points de IList à un objet qui ne peut être modifié. Si le struct est passé par valeur, le pointeur est copié mais c'est OK car il pointe vers quelque chose d'immuable. Si votre objet est transmis autour d'un lot, il sera également plus rapide, parce qu'il n'y a pas besoin d'un à chaque fois deepcopy.

Autres conseils

Je ne pense pas que vous pouvez passer votre classe autour des paramètres par valeur parce que « les types de valeurs ne peuvent pas contenir des fonctions membres spéciales définies par l'utilisateur » ( C3417 de ) tel que le constructeur de copie.

Vous pouvez obtenir un effet similaire en utilisant:

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

Dans votre code C # alors que vous auriez:

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

qui est presque aussi propre que la syntaxe de style Settings settings1 = settings2; vous obtenez avec passage par valeur.

Qu'en est-List<Params>^% Params; List<Params%>^% Params; alternative?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top