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

Das Ergebnis unterscheidet sich von dem, was ich will.
Gibt es eine Möglichkeit, ohne Schleifen zu konvertieren?Wie konvertiert man int [] in kurz []?

+1

Die einfache Antwort ist nein - int verwendet 4 Bytes, verwenden Sie kurze Hosen 2 Bytes - also müssen Sie im Grunde alternative Bytepaare kopieren. Die Antworten, die unten gegeben werden, werden funktionieren - aber unter den Deckungen der Methoden werden sie Schleifen verwenden. Abhängig von der Größe Ihrer Arrays ist es möglich, schnellere Lösungen mit einer eigenen Methode zu schreiben. – PaulF

Antwort

5

Sie können die Array.ConvertAll-Methode verwenden.

Beispiel:

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

Diese Methode nimmt ein Eingangsarray und einen Konverter und das Ergebnis wird die gewünschte Array sein.

Bearbeiten: Eine noch kürzere Version wäre die Verwendung der vorhandenen Convert.ToInt16-Methode. in ConvertAll:

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

Also, wie funktioniert ConvertAll? Schauen wir uns die Implementierung einen Blick:

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; 
} 

die eigentliche Frage zu beantworten ... nein, an einem gewissen Punkt wird es eine Schleife beteiligt, um alle Werte zu konvertieren. Sie können es entweder selbst programmieren oder bereits erstellte Methoden verwenden.

0

Int ist 32 Bit lang und kurz ist 16 Bit lang, so dass die Art des Kopierens von Daten nicht richtig funktioniert.

Universal-Weg wäre, ein Verfahren zu schaffen ints zu Shorts konvertieren:

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

und dann zu verwenden:

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

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

Warum sollte das Erstellen einer zusätzlichen Methode der einfachste Weg sein, wenn ich mit einer Zeile fertig werden kann? – Nino

+0

Gibt es einen Grund für OP, eine Methode zu schreiben, wenn .NET diese Funktionalität bereits bietet - siehe Antwort von Milster. – PaulF

+1

'iBuf.Cast ()' bereits tut dies – Slai