Creating a generic IList instance using reflection
I am trying to create a generic list of objects using refl开发者_开发百科ection. The below code throws an error Cannot create an instance of an interface. . I could change the IList to List and it works fine, but I was wondering if there is way to get this working with an IList.
var name = typeof (IList<T>).AssemblyQualifiedName;
Type type = Type.GetType(name);
var list = Activator.CreateInstance(type);
No, it is not possible to create an instance of an interface.
How should .NET (or rather the Activator.CreateInstance method) decide which implementation of that interface that it should instantiate ?
You can't do :
IList<int> l = new IList<int>();
either, can you ? You just cannot instantiate an interface, since an interface is merily a definition or a contract that describes which functionality a type should implement.
you'll have to instatiate a concrete class so if you do
var type = Type.GetType(typeof (List<T>).AssemblyQualifiedName);
var list = (Ilist<T>)Activator.CreateInstance(type);
you will be succesfull (as long as you supply a valid value for T of course).
Activator.CreateInstance
method invokes the default constructor to create an instance of the type passed as parameter. This type has to be non-abstract and not interface and have a default constructor in order for this function to succeed.
I don't think you can get this working, because you do not know what type of object you need to create.
You will have the same problem with an abstract class.
Well no, that's impossible. The error message is crystal clear. You cannot create an instance of an interface.
How would it know what specific class you want an instance of? Often, many classes implement the same interface. Should it just pick one at random? ;-)
This has nothing to do with reflection, as you wouldn't be able to 'instantiate' an interface normally either. Only assign objects that implement the interface and then pass the interface reference around.
Obviously you can't instanciate an object of type IList<T>
directly because it is an interface type.
You should try instanciating a List<T>
and then maybe return it as an IList<T>
.
IList<T> Create<T>()
{
Type baseListType = typeof(List<>);
Type listType = baseListType.MakeGenericType(typeof(T));
return Activator.CreateInstance(listType) as IList<T>;
}
Well, you CAN instanciate an interface in C#. But only if you actually tell it how to do so.
Look at http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.coclassattribute.aspx and http://blogs.msdn.com/brada/archive/2004/10/10/240523.aspx
In your case however, it seems that you have misunderstood how interfaces work.
Simply create a list and then return an IList<T> and your calling code will not care that you are actually using a List<T>.
精彩评论