Инициализировать массив структур C /CLI

#c -cli

#c -cli

Вопрос:

Я хочу частично инициализировать массив структур, как в типе C POD. Строка ^ обычно была бы символом *, но управляемый C этого не допускает.

 #include "stdafx.h"

using namespace System;

ref struct Field
{
    String^ name;
    int fences;
    int length;
};

int main(array<System::String ^> ^args)
{
    array<Field^>^ farm =
    {
        { "eenie", 10 },
        { "meenie", 20 },
        { "miny", 4 }
    };

    for each (Field^ field in farm)
    {
        field->length = field->fences * 22;
    }

    return 0;
}
  

Это приводит к

 1>arrayinit.cpp(18): error C2440: 'initializing' : cannot convert from 'const char [6]' to 'Field ^'
1>          Reason: cannot convert from 'const char *' to 'Field ^'
1>          No user-defined-conversion operator available, or
1>          Cannot convert an unmanaged type to a managed type
  

Так что я попытался

 #include "stdafx.h"

using namespace System;

ref struct Field
{
    String^ name;
    int fences;
    int length;
};

int main(array<System::String ^> ^args)
{
    array<Field^>^ farm =
    {
        { String("eenie"), 10 },
        { String("meenie"), 20 },
        { String("miny"), 4 }
    };

    for each (Field^ field in farm)
    {
        field->length = field->fences * 22;
    }

    return 0;
}
  

Теперь я получаю

 1>arrayinit.cpp(18): error C2440: 'initializing' : cannot convert from 'System::String' to 'Field ^'
1>          No user-defined-conversion operator available, or
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>arrayinit.cpp(18): error C2078: too many initializers
  

Почти в каждом примере, который я рассматривал, рассказывается только о том, как инициализировать массив строк или целых чисел. Я не нашел способа инициализации массива структур, содержащих строки.

Есть ли простой способ сделать это или мне нужно создать специальный конструктор и gcnew каждый элемент?

Ответ №1:

Я обнаружил, что могу обновлять каждый элемент с помощью специального конструктора. Есть ли более простой способ сделать это, аналогичный инициализации POD?

 #include "stdafx.h"

using namespace System;

ref struct Field
{
    String^ name;
    int fences;
    int length;

    Field(String^ x, int in_fences)
    {
        name = x;
        fences = in_fences;
    }
};

int main(array<System::String ^> ^args)
{
    array<Field^>^ farm =
    {
        gcnew Field("eenie", 10 ),
        gcnew Field("meenie", 20 ),
        gcnew Field("miny", 4 )
    };

    for each (Field^ field in farm)
    {
        field->length = field->fences * 22;
    }

    return 0;
}
  

В качестве альтернативы, поле if изменяется на значение вместо ссылки,

 #include "stdafx.h"

using namespace System;

value struct Field
{
    String^ name;
    int fences;
    int length;

    Field(String^ x, int in_fences)
    {
        name = x;
        fences = in_fences;
    }

    void Init()
    {
        length = fences * 22;
    }
};

int main(array<System::String ^> ^args)
{
    array<Field>^ farm =
    {
        Field("eenie", 10 ),
        Field("meenie", 20 ),
        Field("miny", 4 )
    };

    for each (Field% field in farm)
    {
        field.Init();
    }

    return 0;
}
  

Это немного лучше, чем gcnewing каждое поле.

Комментарии:

1. Убедитесь, что вы понимаете, что значит использовать value struct и как это меняет поведение. Одна вещь, которую я всегда видел в C / CLI, заключается в том, что она редко, если вообще когда-либо, элегантна. Он разработан для работы, но это все (все, что C # делает легко и лаконично, обычно отсутствует).

2. Да — я понимаю различия и подводные камни между ссылкой и значением. Я был вынужден использовать C / CLI из-за WinForms. Можно было бы использовать сочетание C и C / CLI, но проще, если весь код написан на одном языке.

3. Я использую C / CLI только в качестве связующего звена между. Чистый код и C (мой собственный или в библиотеках). Я бы предпочел иметь три языка, чем иметь дело с неуклюжим синтаксисом C / CLI для гораздо большего.