views:

586

answers:

8

I am trying to create a generic list of objects using reflection. 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);
+3  A: 

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.

Darin Dimitrov
+2  A: 

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.

Wim Hollebrandse
+7  A: 

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.

Frederik Gheysels
+2  A: 

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.

GvS
+2  A: 

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>.

fredlegrain
+2  A: 

you'll have to instatiate a concrete class so if you do

var type = Type.GetType(typeof (List<T>));
var list = (Ilist<T>)Activator.CreateInstance(type);

you will be succesfull (as long as you supply a valid value for T of course).

Rune FS
A: 
IList<T> Create<T>()
{
    Type baseListType = typeof(List<>);
    Type listType = baseListType.MakeGenericType(typeof(T));
     return Activator.CreateInstance(listType) as IList<T>;
}
Mel Gerats
Your snippet is faulty. typeof(int) should be typeof(T). You should try to compile and run it. I haven't but then again I don't need to to tell it is wrong. Fix it and I fix the vote. ;-)
Sky Sanders
you're right! fixed.
Mel Gerats
A: 

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>.

Cine