>

C ++로 작성된 오래된 프로젝트를 C #으로 다시 작성하는 데 바쁩니다.

내 임무는 가능한 한 원본에 가깝게 기능하도록 프로그램을 다시 작성하는 것입니다.

다양한 파일 처리 중에이 프로그램을 작성한 이전 개발자는 파일을 작성해야하는 설정된 형식에 해당하는 많은 필드를 포함하는 구조를 생성하므로 모든 작업이 이미 완료되었습니다.

이 필드는 모두 바이트 배열입니다. C ++ 코드는 memset 를 사용합니다.  이 전체 구조를 모든 공백 문자 ( 0x20 )로 설정 ). 한 줄의 코드. 쉬워요.

이 파일은 결국이 형식의 파일을 기대하는 유틸리티이기 때문에 매우 중요합니다. 내가해야 할 일은이 구조체를 C #의 클래스로 변경하는 것이지만 각 바이트 배열을 모든 공백 문자로 쉽게 초기화하는 방법을 찾을 수 없습니다.

내가해야 할 일은 클래스 생성자에서 이것입니다 :

//Initialize all of the variables to spaces.
int index = 0;
foreach (byte b in UserCode)
{
    UserCode[index] = 0x20;
    index++;
}

이것은 잘 작동하지만 더 간단한 방법이 있어야합니다. 어레이가 UserCode = new byte[6] 로 설정된 경우  생성자에서 바이트 배열은 기본 null 값으로 자동 초기화됩니다. 선언시 모든 공간이되도록 할 수있는 방법이 없어서 클래스 생성자를 호출 할 때 다음과 같이 바로 초기화됩니다. 아니면 일부 memset 같은 기능?

  • 답변 # 1

    작은 배열의 경우 배열 초기화 구문을 사용하십시오 :

    var sevenItems = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
    
    

    더 큰 어레이의 경우 표준 for 를 사용하십시오  고리. 가장 읽기 쉽고 효율적인 방법입니다 :

    var sevenThousandItems = new byte[7000];
    for (int i = 0; i < sevenThousandItems.Length; i++)
    {
        sevenThousandItems[i] = 0x20;
    }
    
    

    물론이 작업을 많이해야한다면 코드를 간결하게 유지하는 데 도움이되는 도우미 메서드를 만들 수 있습니다 :

    byte[] sevenItems = CreateSpecialByteArray(7);
    byte[] sevenThousandItems = CreateSpecialByteArray(7000);
    // ...
    public static byte[] CreateSpecialByteArray(int length)
    {
        var arr = new byte[length];
        for (int i = 0; i < arr.Length; i++)
        {
            arr[i] = 0x20;
        }
        return arr;
    }
    
    

  • 답변 # 2

    처음으로 배열을 만들려면 이것을 사용하십시오 :

    byte[] array = Enumerable.Repeat((byte)0x20, <number of elements>).ToArray();
    
    

    와이즈 비즈 교체  원하는 배열 크기로.

  • 답변 # 3

    Enumerable.Repeat ()

    100 개의 항목을 0x20으로 초기화 한 배열 :

    <number of elements>
    
    

  • 답변 # 4

    byte[] arr1 = Enumerable.Repeat(0x20,100).ToArray();
    
    

  • 답변 # 5

    작은 배열을 초기화해야하는 경우 다음을 사용할 수 있습니다 :

    var array = Encoding.ASCII.GetBytes(new string(' ', 100));
    
    

    더 큰 배열이 있다면 다음을 사용할 수 있습니다 :

    byte[] smallArray = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
    
    

    단순하고 다음 남자/여자가 쉽게 읽을 수있는 것. 그리고 99.9 %의 시간이 충분할 것입니다. (일반적으로 BestOption ™이됩니다)

    그러나 실제로 정말 빠른 속도가 필요한 경우 P/invoke를 사용하여 최적화 된 memset 메서드를 호출하면 다음과 같습니다. (여기 사용하기 좋은 수업으로 마무리했습니다)

    byte[] bitBiggerArray Enumerable.Repeat(0x20, 7000).ToArray();
    
    

    사용법 :

    public static class Superfast
    {
        [DllImport("msvcrt.dll",
                  EntryPoint = "memset",
                  CallingConvention = CallingConvention.Cdecl,
                  SetLastError = false)]
        private static extern IntPtr MemSet(IntPtr dest, int c, int count);
        //If you need super speed, calling out to M$ memset optimized method using P/invoke
        public static byte[] InitByteArray(byte fillWith, int size)
        {
            byte[] arrayBytes = new byte[size];
            GCHandle gch = GCHandle.Alloc(arrayBytes, GCHandleType.Pinned);
            MemSet(gch.AddrOfPinnedObject(), fillWith, arrayBytes.Length);
            return arrayBytes;
        }
    }
    
    
    byte[] oneofManyBigArrays = Superfast.InitByteArray(0x20,700000);

관련 자료

  • 이전 c# - NUnit이 MSTestAdapter/MSTestFramework DLL을로드하지 못하고"테스트를 찾을 수 없습니다"
  • 다음 ruby on rails - OmniAuth + 트윗 가져 오기, FB 장소 등