Reputation: 3243
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
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
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
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