ただの愚痴です。
なんしか、↓これがコンパイル通るのに実行時にキャストエラーになるのが納得いかない。
using System; using System.Collections.Generic; namespace GenericTest { class Program { private static void Fn1(object list) { foreach (var i in (IList<int>)list) // ここでキャストエラー { Console.WriteLine(i); } } private static object Fn2(List<int> list1) { var list2 = new List<object>(); foreach (var o in list1) { list2.Add(o); } return list2; } public static void Main(string[] args) { var list1 = new List<int>() { 1, 2, 3 }; Fn1(Fn2(list1)); } } }
恐らく、list2に要素を詰めなおしているのが原因なんだと思うけど、こういう書き方はc#ではできないっぽい。Fn1
が変更できないのであれば、詰めなおさないようにプログラムを書き直す。Fn2
が変更できないのであれば、Fn1
のキャストをIList<int>
じゃなくて IList
を使うようにする。できればコンパイル時にエラーになってほしいけど、object型が間に挟まっている以上無理っぽい。
IListの要素にインターフェースを強制したいのであれば var
じゃなくて 型を明示するのがよさそう。
using System; using System.Collections; using System.Collections.Generic; namespace GenericTest { interface IValue { object Value(); } class Number : IValue { private int i; public Number(int i) { this.i = i; } public object Value() { return i; } } class Text : IValue { private string s; public Text(string s) { this.s = s; } public object Value() { return s; } } class Program { private static void Fn1(object list) { // var じゃなくて IValueを使う foreach (IValue o in (IList)list) { Console.WriteLine(o.Value()); } } private static object Fn2(List<IValue> list1) { var list2 = new List<object>(); foreach (var o in list1) { list2.Add(o); } return list2; } public static void Main(string[] args) { var list1 = new List<IValue>() { new Number(1), new Text("2"), new Number(3), }; Fn1(Fn2(list1)); } } }