2017-06-01 432 views
2
int[] iBuf = new int[2]; 
iBuf[0] = 1; 
iBuf[1] = 2; 

short[] sBuf = new short[2]; 
Buffer.BlockCopy(iBuf, 0, sBuf, 0, 2); 

result 
iBuf[0] = 1 
sBuf[0] = 1 
iBuf[1] = 2 
sBuf[1] = 0 

My desired result 
iBuf[0] = 1 
sBuf[0] = 1 
iBuf[1] = 2 
sBuf[1] = 2 

結果與我想要的不同。
有沒有辦法轉換而不使用循環?如何將int []轉換爲short []?

+1

簡單的答案是否定的 - INT使用4個字節,短褲使用2字節 - 所以基本上你需要複製交替的字節對。下面給出的答案是可行的 - 但是在它們將使用循環的方法的覆蓋下。根據你陣列的大小,可以用你自己的方法編寫更快的解決方案。 – PaulF

回答

5

您可以使用Array.ConvertAll方法。

實施例:

int[] iBuf = new int[2]; 
    ... 
short[] sBuf = Array.ConvertAll(iBuf, input => (short) input); 

此方法需要一個輸入陣列和一個轉換器,其結果將是您所希望的陣列。

編輯: 甚至更​​短的版本將使用現有的Convert.ToInt16方法。 inside ConvertAll:

int[] iBuf = new int[5]; 
short[] sBuf = Array.ConvertAll(iBuf, Convert.ToInt16); 

那麼,ConvertAll是如何工作的?讓我們來看看實現:

public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array, Converter<TInput, TOutput> converter) 
{ 
    if (array == null) 
    { 
     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); 
    } 

    if (converter == null) 
    { 
     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.converter); 
    } 

    Contract.Ensures(Contract.Result<TOutput[]>() != null); 
    Contract.Ensures(Contract.Result<TOutput[]>().Length == array.Length); 
    Contract.EndContractBlock(); 


    TOutput[] newArray = new TOutput[array.Length]; 

    for (int i = 0; i < array.Length; i++) 
    { 
     newArray[i] = converter(array[i]); 
    } 
    return newArray; 
} 

要回答這個問題實際......不,在某些時候會有涉及到的所有值轉換循環。您可以自己編程或使用已建立的方法。

0

int是32位長,16位長,所以複製數據的方式將無法正常工作。

通用的辦法是創造整數轉換成短褲的方法:

public IEnumerable<short> IntToShort(IEnumerable<int> iBuf) 
{ 
    foreach (var i in iBuf) 
    { 
     yield return (short)i; 
    } 
} 

,然後使用它:

int[] iBuf = new int[2]; 
iBuf[0] = 1; 
iBuf[1] = 2; 

short[] sBuf = IntToShort(iBuf).ToArray(); 
+1

爲什麼創建額外的方法是最簡單的方法,當我可以完成一條線? – Nino

+0

當.NET已經提供了這個功能時,是否有任何理由讓OP編寫一個方法 - 請參閱Milster的答案。 – PaulF

+1

'iBuf.Cast ()'已經這樣做 – Slai