27276


デシリアライザのようなものを作るにあたり、文字列から指定した型に変換してプロパティに設定する、というのは `TypeConverter` と
`PropertyDescriptor` で実現できました。それで次は型付けされたコレクションに対応しようと考えています。

最初に考えたのは次のようなコードでした。

[code]

    string[] input = new [] { "1", "2", "3" };
    PropertyDescriptor prop = /* int[] なプロパティを指している */ ;
    var converted = input.Select(prop.Converter.ConvertFrom).ToArray();
    prop.SetValue(converted);
    
[/code]

しかしこれでは `object[]` になってしまい、 `int[]`
のプロパティに代入することができません。このような配列を作るにはどうするとよいでしょうか？

`Activator.CreateInstance()` のようにコンパイル時には `object` で要素を受け取り、`Type`
で指定した型の配列を作るメソッドがないものかと思ったのですが、ないようで。。


CC BY-SA 3.0
2016-07-02T14:47:27.763
27274
2016-07-03T04:51:14.423
8000
question
c#
Typeで示される型を要素に持つ配列を作り、値をまとめてセットするには？


質問を書いて間もないですが、 `Array` 型の存在に気づきました。要素の値を指定して初期化こそできないものの、`Type` からの生成、`object`
型での代入ができるようです。

[code]

    string[] input = new [] { "1", "2", "3" };
    PropertyDescriptor prop = /* int[] なプロパティを指している */ ;
    
    Array converted = Array.CreateInstance(prop.PropertyType.GetElementType();
    for (int i = 0; i < input.Length; ++i) {
        converted.SetValue(prop.Converter.ConvertFrom(input[i]), i);
    }
    
    prop.SetValue(converted);
    
[/code]

あるいは変換結果を `object[]` にしておけば、`Array.Copy()` を使うこともできます。

[code]

    string[] input = new [] { "1", "2", "3" };
    PropertyDescriptor prop = /* int[] なプロパティを指している */ ;
    
    object[] converted = input.Select(prop.Converter.ConvertFrom).ToArray();
    Array typedarr = Array.CreateInstance(prop.PropertyType.GetElementType();
    Array.Copy(converted, typedarr, converted.Length);
    
    prop.SetValue(typedarr);
    
[/code]

さらには `Array.ConvertAll()`
というメソッドで変換しながら別の配列に・・・と思ったのですが、これはジェネリクスを使っているため今回は使えませんでした。


CC BY-SA 3.0
2016-07-02T15:05:32.880
27276
2016-07-02T15:18:00.247
2016-07-02T15:18:00.247
8000
8000
27274
answer


[Expression.NewArrayInitメソッド](https://msdn.microsoft.com/ja-
jp/library/system.linq.expressions.expression.newarrayinit\(v=vs.110\).aspx)を使って`Expression`を組み立てるというのは回答としてありでしょうか？  
これでしたら第１引数は`Type`です。


CC BY-SA 3.0
2016-07-03T04:51:14.423
27289
2016-07-03T04:51:14.423
4236
27274
answer