jstuardo
jstuardo

Reputation: 4373

Cannot add constraint for an interface

I have this interface:

namespace Common.Extensions
{
    public interface IExtension
    {
        string FriendlyName { get; }
        string Description { get; }
    }
}

In other class method, I have this definition:

public void LoadExtensions<T>(T tipo) where T : Common.Extensions.IExtension
{

}

Inside the body of that method, I have this:

T extension = Activator.CreateInstance(t) as T;

Where "t" is a type loaded dynamically from a DLL. That type implements IExtension interface.

With that code, I receive this compile time error:

The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint

According to documentation, what I am trying to do is valid. What is missing here?

Jaime

Upvotes: 3

Views: 218

Answers (3)

Thomas Flinkow
Thomas Flinkow

Reputation: 5105

Since you are using the as operator, it is obvious that T cannot be a struct, it will only ever be a class.

Therefore, you could just do what the error message says and add the class constraint like this:

public void LoadExtensions<T>(T tipo) where T : class, Common.Extensions.IExtension
{                                     ^^^^^^^^^^^^^^^

}

Upvotes: 2

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249536

The as operator can only be used with reference types or nullable types (reference). If the interface is implemented by a struct as will not work with it.

You can either constrain T to be a class

public void LoadExtensions(T tipo) where T : class, Common.Extensions.IExtension

Or you can use a regular cast:

T extension = (T)Activator.CreateInstance(t);

NOTE

You could also add a new() constraint to the method to force T to have a default constructor to avoid runtime issues, and not use a cast at all:

public static void LoadExtensions<T>(T tipo) where T : IExtension, new()
{
    T extension = new T();
}

Upvotes: 7

Steve Harris
Steve Harris

Reputation: 5109

You need to include the class keyword to constrain as a class:

public void LoadExtensions<T>(T tipo) where T : class, Common.Extensions.IExtension

But IMO you should use the interface as you do not need to know the type to access it's methods:

Common.Extensions.IExtension extension = (Common.Extensions.IExtension)Activator.CreateInstance(t);

Upvotes: 0

Related Questions