リフレクションを使用してDLLで指定されたクラスのオブジェクトを作成して返す必要があるツールを作成しようとしています。DLLには多くのクラスが含まれている場合があり、クラスには、プリミティブ、ジェネリック、コレクション、および他のクラスのオブジェクトを含む多くの変数が含まれている場合があります。
コレクションの作成に特に問題があります。これは、コレクションの種類(リスト、ディクショナリ、ハッシュセットなど)が事前にわからないためです。コレクションの引数を取得するコードと、コレクションに挿入するランダムオブジェクトを作成するコードを記述しました。しかし、私は実際の挿入プロセス自体で立ち往生しています。
これが私がこれまでに持っているものです:
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);
}