user7127000
user7127000

Reputation: 3243

Typed parameter method to initialize a type ... Why is this invalid?

Example of what I'm trying to do

public class Program
{
    public static void Main()
    {

    }

    private static T Initialize<T>() where T : MyInterface
    {
        if (typeof(T) == typeof(MyImplementation))
        {
            return new MyImplementation();  
        }
        throw new NotSupportedException("Unsupported type");
    }
}

public interface MyInterface
{

}

public class MyImplementation : MyInterface
{

}

To me this seems like it should work (the compiler should know that NewImplementation is a T since T is a MyInterface).

Cannot implicitly convert type 'MyImplementation' to 'T'

Why is this wrong and what is the correct way?

Upvotes: 1

Views: 58

Answers (3)

Amit
Amit

Reputation: 1857

kevin's answer must be solving your concern.

But if due to any reason you don't want to change signature of your method, you can easily cast your object into T and then return it.

It will be the same at calling side and will be compatible at method body.

private static T Initialize<T>() where T : MyInterface
{
    if (typeof(T) == typeof(MyImplementation))
    {
        MyInterface obj = new MyImplementation(/*parameters*/);
        return (T)obj;
    }
    throw new NotSupportedException("Unsupported type");
}

this will handle the scene when you have to pass parameters too while instantiating an object which I am not sure can be possible in the approach of Dmitry !

Upvotes: 0

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186718

As an alternative to Kevin Smith's answer you can add new into where i.e. ensure that every T class has a default constructor

// "where ..., new" - each T must have a default constructor
private static T Initialize<T>() where T : MyInterface, new {
  if (typeof(T) == typeof(MyImplementation)) {
    return new T(); // <- now we can create T which is in fact MyImplementation
  }
  throw new NotSupportedException("Unsupported type");
}

Upvotes: 1

Kevin Smith
Kevin Smith

Reputation: 14436

The return type T might not be a MyImplementation, for example, if we had another type MyOtherImplementation:

public class MyOtherImplementation : MyInterface { }

Then we call the Initialize<T> method, this would return a MyOtherImplementation:

MyOtherImplementation myInterface = Initialize<MyOtherImplementation>();

You'll need to change the return type to the below to make this work as you expect:

    private static MyInterface Initialize<T>() where T : MyInterface
    {
        if (typeof(T) == typeof(MyImplementation))
        {
            return new MyImplementation();
        }
        throw new Exception("Unsupported type");
    }

Upvotes: 4

Related Questions