2018年4月18日水曜日

Netjsに変換する際に起きた配列関連のトラブル2件とその対応

1. List<>とarray[]が混在しているとTypeScriptへの翻訳がうまくいかない

例えばC#で次の型があったとします。
List<List<byte[]>> arraylistlist = new List<List<byte[]>>();

で、リスト0要素目->子リストリスト0要素目->子配列0番目にアクセスしたいと思ったとします。
するとC#では次のように書けます。

byte val = arraylistlist[0][0][0];

ですが、この書き方ですと、NetjsのTypeScript翻訳結果は次の通りになり、うまくいきません。

var val : number = arraylistlist.get_Item(0).get_Item(0).get_Item(0);
理由は、number[]型にget_Itemというメソッドがないからです。

本来は次のように翻訳されるべきです。
var val : number = arraylistlist.get_Item(0).get_Item(0)[0];

TypeScriptは自動生成されるものなので生成後のTypeScriptを手動で修正するのは極力避けたいですよね。
この解決策は容易です。
単純にC#側のコードを2行に分けるだけです。
具体的には
byte[] bytearray = arraylistlist[0][0];
byte b = bytearray[0];
というふうに。
すると、次のように正しく翻訳されます。
var bytearray : number[] = arraylistlist.get_Item(0).get_Item(0);
var val : number = bytearray [0];

2. array.CopyToがない
たとえばC#で以下のようなコードを書いたとします。
byte[] bytearray = new byte[10];
bytearray.CopyTo( dst, 0 );
すると、次のようにTypeScriptに翻訳されます。
var bytearray : number[] = new Array<number>(10);
bytearray.CopyTo(dst, 0);

bytearray はTypeScriptでのnumber[]型なので、CopyToというメソッドを持っていません。 number[]はTypeScriptの基本型なのでNetjsそのものの改造が必要になると思うので、直接対応するには敷居が高そうです。
そこで、Array.CopyToをBuffer.BlockCopyとして書き直してやったうえでmscorlib.tsに次を追記してあげるとうまくいきます。
1
2
3
4
5
6
7
8
9
class Buffer extends NObject
{
  static BlockCopy(src: any[], srcOffset: number, dst: any[], dstOffset : number, count: number ): void
  {
    for (var i = 0; i < count; i++) {
      dst[ i + dstOffset ] = src[ i + srcOffset ] ;
    }
  }
}
まあそんな感じです。
個人的には次にNetjsを使用することはないと思いますが一応。

0 件のコメント:

コメントを投稿