Reputation: 2304
This may be a question about fundamental design.
I want to perform an operation on a mystery object, as long as it implements my interface IMyInterface. And I want one of methods defined by the interace to return an instance of mystery object so...
IMyInterface
{
object GetInstance();
}
public class MysteryObject : IMYInterface
}
public object GetInstance()
{
MysteryObject instance = new MysteryObject();
return instance;
}
}
but this results in unnecessary 'object' types and the overhead associated with those. C# specifically kills this overhead with the use of generic types. It would be ideal to do something like this:
IMyInterface
{
T GetInstance<T>();
}
public class MysteryObject : IMYInterface
}
public MysteryObject GetInstance<MysteryObject>()
{
MysteryObject instance = new MysteryObject();
return instance;
}
}
I know this second example doesn't work. I know the syntax is wrong. ..but I'm wondering if there is a better way to require that an object that implements IMyInterface return an instance of it's own type.
My examples a little weird but i think most will understand the sentiment. Strangely, I've found very little examples or questions around this.
Upvotes: 2
Views: 70
Reputation: 814
You can just make the return type IMyInterface
:
public interface IMyInterface
{
IMyInterface GetInstance();
}
public class MysteryObject : IMyInterface
{
public IMyInterface GetInstance()
{
MysteryObject instance = new MysteryObject();
return instance;
}
}
Or with generics:
public interface IMyInterface<T>
{
T GetInstance();
}
public class MysteryObject : IMyInterface<MysteryObject>
{
public MysteryObject GetInstance()
{
MysteryObject instance = new MysteryObject();
return instance;
}
}
If you want the generic argument to be of type IMyInterface you add constraint like this:
public interface IMyInterface<T>
where T : IMyInterface<T>
{
T GetInstance();
}
Update
Here are some example usages to see what the difference between these 2 versions is:
Returning interface IMyInterface
:
IMyInterface a = new MysteryObject().GetInstance(); // valid
MysteryObject b = new MysteryObject().GetInstance();// invalid
MysteryObject b = (MysteryObject)new MysteryObject().GetInstance(); // valid
Returning the generic type argument from the interface:
IMyInterface<MysteryObject> a = new MysteryObject().GetInstance(); //valid
MysteryObject b = new MysteryObject().GetInstance(); //valid
Upvotes: 4
Reputation: 61349
You almost have it. You need to make the whole interface generic:
IMyInterface<T>
{
T GetInstance();
}
public class MysteryObject : IMYInterface<MysteryObject>
}
public MysteryObject GetInstance()
{
MysteryObject instance = new MysteryObject();
return instance;
}
}
Upvotes: 2