我还是C#的新手,我一直在努力解决阵列上的各种问题。我有一组元数据对象(名称值对),我想知道如何只创建我真正需要的“InputProperty”对象的数量。在这个循环中,我任意设置元素的数量为20,当条目变为null时我试图挽救但是接收端的Web服务不喜欢传递给它的任何null元素:
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;
}
总之,假设我在上面的输入数组中只有3个名值对?不是为名为ip的数组分配20个元素,而是如何对此进行编码,以便ip只有它需要的大小。更新对象通过另一个Web服务传递,因此序列化很重要(即我不能使用namevaluecollection等)。
P.S。是通过“添加评论”工具跟踪已发布问题的唯一方法吗?
答案 0 :(得分:27)
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变量使用:
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;
}
答案 1 :(得分:20)
如果您不想使用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);
}
代码较少,但最终可能会完成相同数量的工作(即创建新数组并复制旧项目)。
答案 2 :(得分:5)
是否需要是一个数组?如果您使用ArrayList或C#中提供的其他对象之一,则不会对内容具有此限制。 Hashtable,IDictionnary,IList等都允许动态数量的元素。
答案 3 :(得分:4)
使用此:
Array.Resize(ref myArr, myArr.Length + 5);
答案 4 :(得分:2)
您可以在方法中使用List并将其转换为最后的数组。但我想如果我们谈论最大值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;
}
答案 5 :(得分:2)
或者在使用System.Linq
的C#3.0中,您可以跳过中间列表:
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;
}
答案 6 :(得分:1)
使用Array.CreateInstance
动态创建数组。
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;
}
答案 7 :(得分:0)
通常,数组需要常量来初始化它们的大小。您可以扫描nvPairs一次以获得长度,然后使用变量长度“动态”创建一个数组,如下所示。
InputProperty[] ip = (InputProperty[])Array.CreateInstance(typeof(InputProperty), length);
但是,我不推荐它。只需坚持
List<InputProperty> ip = ...
...
update.Items = ip.ToArray();
溶液。它的表现并不是那么低,看起来更好看。
答案 8 :(得分:0)
您可以通过以下方式动态创建数组:
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];
}