我正在尝试编写一个工具,我需要使用反射创建和返回 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);
}