2017-06-01 74 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