I am struggling to try to use generic types when the parameter types are not known until runtime. I can get as far as making an object which contains an instance of the specif type (as below), but it is always an "object" and not the generic type that I wanted. I.e. How can I cast the object to the runtime generic type - or how do I access the member functions of the SortedList
Hope the code below makes my question a lot clearer...
Thanks,
Matthew.
// Make a "Type" called General which is "any kind of SortedList":
Type General = typeof(SortedList<,>);
// Make a more specific Type, which is SortedList
// only know that we want
Type specific = General.MakeGenericType(new Type[] { typeof(long), typeof(string) });
// Make an instance:
ConstructorInfo ci = specific.GetConstructor(new Type[] { });
object myList = ci.Invoke(new object[] { });
// Okay, that's great so far. But myList is of type "object" and not
// SortedList
// I can't write: "myList as SortedList
specific wishThisWorkedButItDont = myList as specific;
wishThisWorkedButItDont.Add(100, "hooray!");
PJ MartinsPosted May 29, 2010, 8:32 PM
Type myType = Type.GetType("System.Int32");
object testInt = Convert.ChangeType(100, myType);
testInt = Convert.ChangeType("testing", myType); // throws runtime exception
Matthew BrandPosted May 29, 2010, 9:47 AM
PJ MartinsPosted May 29, 2010, 8:54 AM
Matthew BrandPosted May 29, 2010, 7:50 AM
public class RuntimeSortedList
{
Type KeyType;
Type ValueType;
public object theList;
// Will need to define a method info for each member of SortedList<,>
MethodInfo AddMI;
public RuntimeSortedList(Type KeyType, Type ValueType)
{
this.KeyType = KeyType;
this.ValueType = ValueType;
// Make a "Type" called General which is "any kind of SortedList"
Type General = typeof(SortedList<,>);
// make a more specific type
Type specific = General.MakeGenericType(new Type[] { KeyType, ValueType });
// create an instance of specific
theList = Activator.CreateInstance(specific);
// Define wrappers to expose every SortedList<,> member
AddMI = specific.GetMethod("Add");
}
// Define wrappers to expose every SortedList<,> member
public void Add(object Key, object Value)
{
if (Key.GetType() != KeyType) throw new Exception(string.Format("Key is type {0}, should be {1}.", Key.GetType(), KeyType));
if (Value.GetType() != ValueType) throw new Exception(string.Format("Value is type {0}, should be {1}.", Value.GetType(), ValueType));
AddMI.Invoke( theList, new object [] {Key, Value});
}
}
static void Main(string[] args)
{
RuntimeSortedList rtsl = new RuntimeSortedList(typeof(long), typeof(string));
// Bit annoying that 100 goes in as Int32 because we are passing as "object".
rtsl.Add(100L, "massive bixing overhead?");
}
Matthew BrandPosted May 29, 2010, 6:20 AM
Any ideas?
Thanks,
Matthew.
Matthew BrandPosted May 28, 2010, 4:51 PM
PJ MartinsPosted May 28, 2010, 4:41 PM