C#: Non-Generic classes using generic classes undefined
I have a Generic Interface
public interface TheInterface<T> where T : IObject
I also have an object class that this interface works with
public class SomeObject : IObject
I then have a class that implements the interface
public class ClassThatWorksWithSomeObject : TheInterface<SomeObject>
This all works well enough. Later on I add a class that works with TheInterface class independent 开发者_StackOverflow中文版of what version of IObject he uses.
public class IDoStuffToInterface
{
public IDoStuffToInterface(TheInterface<IObject> interface)
{
//bla bla
}
}
Problem is I can't pass ClassThatWorksWithSomeObject
in there, even if It inherits from the intreface and it's generic object inherits from IObject
.
I guess there are some cases that it could be hurtful if it did, but I can't think of any.
Is there a way to do this better?
I don't know the detail impelmentation, you can try:
public interface TheInterface<out T> where T : IObject
if you are using C#4.0
I think what you're doing should work, but you may need to use the covariance and contravariance keywords.
You need to make you definition of TheInterface
covariant so that it accepts the wider types of IObject
:
public interface TheInterface<out T> where T : IObject
You should be able to do this in C#4.0 by marking the interface type as contravariant, but I think you can also get around this by making the IDoStuffInterface generic as well.
public class IDoStuffToInterface<T> where T : IObject
{
public IDoStuffToInterface(TheInterface<T> interface)
{
//bla bla
}
}
Since SomeObject
qualifies for T and ClassThatWorksWithSomeObject
implements TheInterface<SomeObject>
, it should be acceptable as a parameter.
The other way I saw mentioned by tvanfosson was to make your IDoStuffToInterface class generic. That would work nicely as well, if (as it appears in the example) the TheInterface is being passed into the constructor and (presumably) stored in the class.
However, if it were just a function (or even a constructor) that uses the TheInterface and it isn't being stored in the class, it would probably be better to make the function itself generic and leave the class alone. For example:
public class IDoStuffToInterface
{
public void DoSomething<T>(TheInterface<T> theInterface) where T : IObject
{
//bla bla
}
}
This would allow you to do the following:
ClassThatWorksWithSomeObject myObject = new ClassThatWorksWithSomeObject();
IDoStuffToInterface actor = new IDoStuffToInterface();
actor.DoSomething(myObject);
That compiles without any problem because the compiler is able to tell by inference that you are actually calling
actor.DoSomething<SomeObject>(myObject);
Now, I think that using covariance is still probably the best option if you are in control of the interface definition. But I wanted to add this as another option for when you don't have that degree of control in your interface.
精彩评论