#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 для гораздо большего.