문제

나는 여전히 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];

    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top