Если вы не хотите использовать List
, ArrayList
или другую коллекцию динамического размера, а затем конвертировать в массив (кстати, этот метод я бы порекомендовал), то вы нужно выделить массив для его максимально возможного размера, отследить, сколько элементов вы поместили в него, а затем создать новый массив, содержащий только эти элементы:
private Update BuildMetaData(MetaData[] nvPairs)
{
Update update = new Update();
InputProperty[] ip = new InputProperty[20]; // how to make this "dynamic"
int i;
for (i = 0; i < nvPairs.Length; i++)
{
if (nvPairs[i] == null) break;
ip[i] = new InputProperty();
ip[i].Name = "udf:" + nvPairs[i].Name;
ip[i].Val = nvPairs[i].Value;
}
if (i < nvPairs.Length)
{
// Create new, smaller, array to hold the items we processed.
update.Items = new InputProperty[i];
Array.Copy(ip, update.Items, i);
}
else
{
update.Items = ip;
}
return update;
}
Альтернативным методом будет всегда присваивайте update.Items = ip;
и затем изменяйте размер при необходимости:
update.Items = ip;
if (i < nvPairs.Length)
{
Array.Resize(update.Items, i);
}
Это меньше кода, но, скорее всего, в конечном итоге выполнит тот же объем работы (т. е. создаст новый массив и скопирует старые элементы).
Нужно ли быть массивом? Если вы используете ArrayList или один из других объектов, доступных в C #, у вас не будет этого ограничения на контент с. Hashtable, IDictionnary, IList и т. Д. Все позволяют динамическое количество элементов.
InputProperty[] ip = new InputProperty[nvPairs.Length];
Или, можно использовать список как так:
List<InputProperty> list = new List<InputProperty>();
InputProperty ip = new (..);
list.Add(ip);
update.items = list.ToArray();
Другая вещь, на которую я хотел бы указать в C#, можно объявить международное переменное использование в для цикла прямо в цикла:
for(int i = 0; i<nvPairs.Length;i++
{
.
.
}
И просто потому что я нахожусь в настроении, вот более чистый способ сделать этот метод IMO:
private Update BuildMetaData(MetaData[] nvPairs)
{
Update update = new Update();
var ip = new List<InputProperty>();
foreach(var nvPair in nvPairs)
{
if (nvPair == null) break;
var inputProp = new InputProperty
{
Name = "udf:" + nvPair.Name,
Val = nvPair.Value
};
ip.Add(inputProp);
}
update.Items = ip.ToArray();
return update;
}
Вы могли использовать Список в методе и преобразовать его к массиву в конце. Но я думаю, говорим ли мы о макс. значении 20, Ваш код быстрее.
private Update BuildMetaData(MetaData[] nvPairs)
{
Update update = new Update();
List<InputProperty> ip = new List<InputProperty>();
for (int i = 0; i < nvPairs.Length; i++)
{
if (nvPairs[i] == null) break;
ip[i] = new InputProperty();
ip[i].Name = "udf:" + nvPairs[i].Name;
ip[i].Val = nvPairs[i].Value;
}
update.Items = ip.ToArray();
return update;
}
Или в использовании C# 3.0 System.Linq
можно пропустить промежуточный список:
private Update BuildMetaData(MetaData[] nvPairs)
{
Update update = new Update();
var ip = from nv in nvPairs
select new InputProperty()
{
Name = "udf:" + nv.Name,
Val = nv.Value
};
update.Items = ip.ToArray();
return update;
}
Как правило, массивы требуют, чтобы константы инициализировали свой размер. Вы могли развернуться по nvPairs однажды для получения длины, затем "динамично" создать массив с помощью переменной для длины как это.
InputProperty[] ip = (InputProperty[])Array.CreateInstance(typeof(InputProperty), length);
Я не рекомендовал бы это, все же. Просто палка с
List<InputProperty> ip = ...
...
update.Items = ip.ToArray();
решение. Дело не в этом намного менее производительный, и лучше выглядящий путь.