I am still new to C# and I've been struggling with various issues on arrays. I've got an array of metadata objects (name value pairs) and I would like to know how to create only the number of "InputProperty" objects that I truly need. In this loop I've arbitrarily set the number of elements to 20 and I try to bail out when the entry becomes null but the web service on the receiving end of this does not like any null elements passed to it:
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;
}
update.Items = ip;
return update;
}
In summary, say I only have 3 namevalue pairs in the above input array? Rather than allocate 20 elements for the array called ip, how can code this so ip is only as big as it needs to be. The update object is passed across another webservice so serialization is important (i.e. I can't use namevaluecollection, etc.).
p.s. Is the only way to followup on a posted question through the "add comments" facility?
This question is related to
c#
arrays
object
array-initialize
Or in C# 3.0 using System.Linq
you can skip the intermediate list:
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;
}
Does is need to be an array? If you use an ArrayList or one of the other objects available in C#, you won't have this limitation to content with. Hashtable, IDictionnary, IList, etc.. all allow a dynamic number of elements.
You could use List inside the method and transform it to an array at the end. But i think if we talk about an max-value of 20, your code is faster.
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;
}
Use Array.CreateInstance
to create an array dynamically.
private Update BuildMetaData(MetaData[] nvPairs)
{
Update update = new Update();
InputProperty[] ip = Array.CreateInstance(typeof(InputProperty), nvPairs.Count()) as InputProperty[];
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;
}
update.Items = ip;
return update;
}
InputProperty[] ip = new InputProperty[nvPairs.Length];
Or, you can use a list like so:
List<InputProperty> list = new List<InputProperty>();
InputProperty ip = new (..);
list.Add(ip);
update.items = list.ToArray();
Another thing I'd like to point out, in C# you can delcare your int variable use in a for loop right inside the loop:
for(int i = 0; i<nvPairs.Length;i++
{
.
.
}
And just because I'm in the mood, here's a cleaner way to do this method 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;
}
Typically, arrays require constants to initialize their size. You could sweep over nvPairs once to get the length, then "dynamically" create an array using a variable for length like this.
InputProperty[] ip = (InputProperty[])Array.CreateInstance(typeof(InputProperty), length);
I wouldn't recommend it, though. Just stick with the
List<InputProperty> ip = ...
...
update.Items = ip.ToArray();
solution. It's not that much less performant, and way better looking.
You can create an array dynamically in this way:
static void Main()
{
// Create a string array 2 elements in length:
int arrayLength = 2;
Array dynamicArray = Array.CreateInstance(typeof(int), arrayLength);
dynamicArray.SetValue(234, 0); // ? a[0] = 234;
dynamicArray.SetValue(444, 1); // ? a[1] = 444;
int number = (int)dynamicArray.GetValue(0); // ? number = a[0];
int[] cSharpArray = (int[])dynamicArray;
int s2 = cSharpArray[0];
}
Use this:
Array.Resize(ref myArr, myArr.Length + 5);
Source: Stackoverflow.com