C#에서 배열 길이를 동적으로 설정하는 방법
-
22-08-2019 - |
문제
나는 여전히 C#을 처음 접했고 배열에 대한 다양한 문제로 어려움을 겪고 있습니다. 메타 데이터 객체 (이름 값 쌍) 배열이 있으며 진정으로 필요한 "입력 프로퍼티"객체의 수만 생성하는 방법을 알고 싶습니다. 이 루프에서 나는 요소 수를 20로 임의로 설정했으며 항목이 무효화되면 구제하려고하지만이를 수신하는 웹 서비스는 다음과 같은 무효 요소가 마음에 들지 않습니다.
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 가지 요소를 할당하는 대신,이를 코딩하는 방법은 필요한만큼 크게 코딩 할 수 있습니다. 업데이트 객체는 다른 웹 서비스를 통해 전달되므로 직렬화가 중요합니다 (예 : NameValueCollection 등을 사용할 수 없습니다).
추신 : "댓글 추가"시설을 통해 게시 된 질문에서 후속 조치를 취하는 유일한 방법은 무엇입니까?
해결책
사용하고 싶지 않은 경우 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);
}
코드는 적지 만 동일한 양의 작업을 수행하게 될 것입니다 (즉, 새 배열을 만들고 이전 항목을 복사합니다).
다른 팁
InputProperty[] ip = new InputProperty[nvPairs.Length];
또는 다음과 같은 목록을 사용할 수 있습니다.
List<InputProperty> list = new List<InputProperty>();
InputProperty ip = new (..);
list.Add(ip);
update.items = list.ToArray();
내가 지적하고 싶은 또 다른 것은 C#에서 루프 내부의 루프에서 int 변수 사용을 삭제할 수 있습니다.
for(int i = 0; i<nvPairs.Length;i++
{
.
.
}
그리고 내가 분위기에 있기 때문에 여기 에이 방법을 수행하는 더 깨끗한 방법이 있습니다.
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;
}
배열이어야합니까? ArrayList 또는 C#에서 사용 가능한 다른 개체 중 하나를 사용하는 경우 내용에 대한 제한이 없습니다. Hashtable, Idictionnary, Ilist 등은 모두 동적 수의 요소를 허용합니다.
이것을 사용하십시오 :
Array.Resize(ref myArr, myArr.Length + 5);
메소드 내부의 목록을 사용하여 끝의 배열로 변환 할 수 있습니다. 그러나 우리가 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;
}
사용 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;
}
일반적으로 배열은 크기를 초기화하기 위해 상수가 필요합니다. 길이를 얻기 위해 NVPairs를 한 번 스윕 한 다음 길이와 같은 변수를 사용하여 배열을 "동적으로"만들 수 있습니다.
InputProperty[] ip = (InputProperty[])Array.CreateInstance(typeof(InputProperty), length);
그래도 나는 그것을 추천하지 않을 것이다. 그냥 고수하십시오
List<InputProperty> ip = ...
...
update.Items = ip.ToArray();
해결책. 그다지 성능이 떨어지지 않으며 더 잘 보입니다.
이러한 방식으로 배열을 동적으로 만들 수 있습니다.
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];
}