Skip to content

Instantly share code, notes, and snippets.

@takeshik
Created September 22, 2011 04:02
Show Gist options
  • Save takeshik/1234004 to your computer and use it in GitHub Desktop.
Save takeshik/1234004 to your computer and use it in GitHub Desktop.
return this.Elements.ReduceAll(symbols)
// es = 配列の全要素 (評価済)
.Let(es => es
.Select(e => e.Type)
.Distinct()
// ts = 配列に含まれる全ての型
.Let(ts => ts
.SelectMany(t => t.GetConvertibleTypes())
// 配列の要素の型から導ける全ての基底型、実装インターフェイスの集合を取得し
.Distinct()
// Object を取り除き、Object からの継承ルートの遠さで並び替え
.Except(EnumerableEx.Return(typeof(Object)))
.OrderByDescending(t => EnumerableEx
.Generate(t, _ => _.BaseType != null, _ => _.BaseType, _ => _)
.Count()
)
// 末尾に Object を追加
.Concat(EnumerableEx.Return(typeof(Object)))
// …したリストのうち、配列の全要素が互換性のある最初の型を選択
.First(t => ts.All(t.IsAssignableFrom))
)
// t = 決定された配列の型
.Let(t => NewArrayInit(
t,
// t が参照型の場合、値型の要素は明示的にキャストが必要
t.IsValueType
? es
: es.Select(e => e.Type.IsValueType
? Convert(e, t)
: e
)
))
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment