在运行时填充泛型集合

时间:2012-12-13 22:42:12

标签: c# generics collections

我正在尝试编写一个工具,我需要使用反射创建并返回DLL中给定的类的对象。 DLL可以包含许多类,并且类可以具有许多变量,包括基元,泛型,集合和另一类的对象。

我在填充集合时遇到了特别的麻烦,因为我事先并不知道它将是什么样的集合(无论是List,Dictionary,HashSet还是其他任何东西)。我编写了代码来获取集合的参数,并编写了一些代码来创建一些随机对象以插入集合中;但我坚持实际插入过程本身。

这是我到目前为止所做的:

if (fieldType.IsGenericType)
{
    Type[] typeArgs = fieldType.GetGenericArguments(); // Get the arguments, for eg, List<String> will return String as argument
    object genericObj;

    /* Check if it has generic type definition or specific type definition then create the object */
    if (fieldType.IsGenericTypeDefinition)
    {
        Type constructGeneric = fieldType.MakeGenericType(typeArgs);
        genericObj = Activator.CreateInstance(constructGeneric);
    }
    else
    {
        genericObj = Activator.CreateInstance(fieldType);
    }
    //populate genericObj with 7 key-val pair --> in case of List<String> I want to populate the List with 7 Strings, in case of Dictionary<int,string> I want 7 <int, string> pairs
    for (int i = 0; i < 7; i++)
    {
        Object[] oArr = new Object[typeArgs.Length];
        int ctr = 0;
        foreach (Type ta in typeArgs)
        {
            if (ta.IsPrimitive || Type.GetTypeCode(ta) == TypeCode.String)
            {
                Random rnd = new Random();
                var buffer = new byte[sizeof(Int64)];
                rnd.NextBytes(buffer);
                switch (Type.GetTypeCode(ta))
                {
                    case TypeCode.Boolean:
                        oArr[ctr] = (rnd.Next(100) % 2 == 0);
                        break;
                    case TypeCode.Byte:
                        oArr[ctr] = buffer[0];
                        break;
                    case TypeCode.SByte:
                        oArr[ctr] = (sbyte)buffer[0];
                        break;
                    case TypeCode.Char:
                        oArr[ctr] = Convert.ToInt32(Math.Floor(26 * rnd.NextDouble() + 65));
                        break;
                    case TypeCode.Decimal:
                        oArr[ctr] = NextDecimal(rnd);
                        break;
                    case TypeCode.Double:
                        oArr[ctr] = rnd.NextDouble() * rnd.Next(Int32.MaxValue);
                        break;
                    case TypeCode.Single:
                        var buf = new byte[sizeof(Single)];
                        rnd.NextBytes(buf);
                        oArr[ctr] = BitConverter.ToSingle(buffer, 0);
                        break;
                    case TypeCode.Int32:
                        oArr[ctr] = rnd.Next(Int32.MinValue, Int32.MaxValue);
                        break;
                    case TypeCode.UInt32:
                        oArr[ctr] = rnd.Next(Int32.MaxValue) + (rnd.Next(100) % 2) * rnd.Next(Int32.MaxValue);
                        break;
                    case TypeCode.Int64:
                        oArr[ctr] = BitConverter.ToInt64(buffer, 0);
                        break;
                    case TypeCode.UInt64:
                        oArr[ctr] = BitConverter.ToUInt64(buffer, 0);
                        break;
                    case TypeCode.Int16:
                        oArr[ctr] = rnd.Next(Int16.MaxValue);
                        break;
                    case TypeCode.UInt16:
                        oArr[ctr] = rnd.Next(Int16.MaxValue) + (rnd.Next(100) % 2) * rnd.Next(Int16.MaxValue);
                        break;
                    case TypeCode.String:
                        oArr[ctr] = RandomString(rnd.Next(100));
                        break;
                    default:
                        oArr[ctr] = 0;
                        break;
                }
            }
            else
            {
                oArr[ctr] = getInstance(dllFile, ta.Name);
            }
            ctr++;
            if(genericObj.GetType().GetGenericTypeDefinition().ToString() == "ICollection") {
                // This is where I am stuck -- HOW TO INSERT??
            }
        }
    }
    //setvalue
    f.SetValue(obj, genericObj);
}

1 个答案:

答案 0 :(得分:0)

与任何其他集合一样..在对象上调用Add方法(或者它可能是Items proeprty的Add方法)