¿Cómo se crea una clase de valor CLI que contiene una lista (o similar) que se pasa por valor?

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

Pregunta

Tenemos una biblioteca de C ++ que utiliza una estructura que contiene un vector de STL de estructuras, así:

struct Params
{
    // values...
}

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

    // values...
}

Estoy escribiendo un envoltorio CLI para la biblioteca, y quiero equivalentes para los tipos struct anteriores. Había estado pensando acerca del uso de una lista como el equivalente de un vector, así:

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

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

    // values...
}

Pero como List es un tipo de referencia, la lista se pasa todo por referencia en lugar de valor. ¿Hay una manera de crear una clase CLI contiene una lista (o similar) que se pasa por valor, junto con el resto de los miembros?

¿Fue útil?

Solución

Estoy de acuerdo con la respuesta de mcdave, que se reduce a que lo que están pidiendo no es compatible.

Estoy especulando que su punto principal no es conseguir real el paso por valor, pero más para conseguir el paso por valor de Comportamiento . Piense en System.String. Eso no es realmente un tipo de valor, pero se pueden pasar las referencias ahí seguro, porque las cadenas no se pueden modificar, sólo se pueden hacer otros nuevos.

Para obtener la misma para obtener una lista, puede hacer Params una propiedad de tipo IList<Param>. Cuando asignándole, copiar el contenido en un nuevo List<Param> y almacenar el puntero IList se obtiene cuando se llama a AsReadOnly(). A partir de ahora, los puntos IList a un objeto que no se puede modificar. Si la estructura se pasa por valor, se copiará el puntero pero está bien porque apunta a algo inmutable. Si el objeto se pasa alrededor de un lote, también será más rápido, porque no hay necesidad de una cada vez deepcopy.

Otros consejos

no creo que pueda pasar su clase Ajustes alrededor de valor debido a que "los tipos de valor no pueden contener funciones miembro especiales definidas por el usuario" ( de C3417 ), tales como el constructor de copia.

Se puede lograr un efecto similar 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;
    }
}

En el código C # que tendría entonces:

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

que es casi tan limpia como la sintaxis de estilo Settings settings1 = settings2; que se obtiene con paso por valor.

¿Qué hay de List<Params>^% Params; alternativamente List<Params%>^% Params;?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top