1. 程式人生 > >根據Type 變數動態建立可變內部型別的泛型

根據Type 變數動態建立可變內部型別的泛型

有的時候我們的泛型中的資料型別是動態變化的. 所以有的時候.我們需要.根據Type引數動態建立.不同內部型別的泛型
例如:List t = new List();
這裡的 int 引數是需要根據情況動態變化的.
所以就出現了.

var rType = typeof(string);
var genericType = typeof(List<>).MakeGenericType(rType);
//這裡的 genericType == typeof(List<string>)

看看下面這個牛B的泛型型別動態轉換方法

        /// <summary>
/// 把字串陣列中的資料,轉換成另外一種泛型型別. /// </summary> /// <param name="values"></param> /// <param name="t"></param> /// <returns></returns> public static dynamic TryParserArray(string[] values, Type t) { //string[] searchArray = value.Split(',');
var genericType = typeof(List<>).MakeGenericType(t); var list = Activator.CreateInstance(genericType); var addMethod = genericType.GetMethod("Add"); foreach (var l in values) { try { var
dValue = Convert.ChangeType(l, t); //dList.Add(dValue); addMethod.Invoke(list, new object[] { dValue }); } catch { } } return list; }

下面這個是連結串列版的.

 /// <summary>
        /// 把字串陣列中的資料,轉換成另外一種泛型型別.
        /// </summary>
        /// <param name="values"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static dynamic TryParserArray(List<string> values, Type t)
        {
            //string[] searchArray = value.Split(',');
            var genericType = typeof(List<>).MakeGenericType(t);
            var list = Activator.CreateInstance(genericType);
            var addMethod = genericType.GetMethod("Add");

            foreach (var l in values)
            {
                try
                {
                    var dValue = Convert.ChangeType(l, t);
                    //dList.Add(dValue);
                    addMethod.Invoke(list, new object[] { dValue });
                }
                catch { }
            }
            return list;
        }

使用示例

//使用在牛B閃閃的linq表示式中.實現 In 表示式
  var Values = new List<string>(){"18","19","20"};
  var rType = typeof(int);

  var genericType = typeof(List<>).MakeGenericType(rType);//等價於 typeof(List<int>) 只是,int可以根據Type動態改變了.更加靈活一些了.

 //用dynamic做裝箱拆箱 
 var searchList = TryParserArray(Values, rType);//這裡返回的是一個泛型連結串列.泛型內型別為 rType指定的型別.  型別已經變成了List<int>型別

 if (searchList.Count > 0)
 {
     var elementList = Expression.Constant(searchList, genericType); //這個等價於 (p=> searchList.Contains(p.age)) 中的searchList
     //Expression convertExpression = Expression.Convert(p, rType);
     list.Add(Expression.Call(elementList, "Contains", null, p));//這個等價於 (p=> searchList.Contains(p.age)) 中的 searchList.Contains(p.age)
 }