I am stuck on the usage of an implementation that is constraint by an interface. My usage is intuitive to me, but does not compile so I am misunderstanding something.
My interfaces:
interface IEntity
{
int ExampleMethod(IContext<IFooBar> context);
}
interface IContext<T> where T : class, IFooBar
{
T FooBar { get; set; }
}
interface IFooBar
{
int Value { get; }
}
My implementations:
class Entity : IEntity
{
public int ExampleMethod(IContext<IFooBar> context)
{
return context.FooBar.Value;
}
}
class Context : IContext<FooBar>
{
public FooBar FooBar { get; set; }
}
class FooBar : IFooBar
{
public int Value { get { return 10; } }
}
Usage of Entity class, where problem is thrown
class UsageOfEntity
{
public UsageOfEntity()
{
var context = new Context();
var entity = new Entity();
int result = entity.ExampleMethod(context);
}
}
The usage of instance context
throws an error:
Argument 1: cannot convert from 'Context' to 'IContext<IFooBar>'
How do I constrain the generic type parameter such that my implementation can be used?
CodePudding user response:
Context is an IContext<FooBar>
not an IContext<IFooBar>
.
Because OP has indicated in the comments that IContext<T>.FooBar
only needs to be read-only, T
can be made covariant:
interface IContext<out T>
where T : class, IFooBar
{
T FooBar { get; }
}
Now, because FooBar
implements IFoobar
, it is valid to use a IContext<FooBar>
in place of a IContext<IFooBar>
:
CodePudding user response:
The problem in your code is that you are trying to convert Context
to Type
IContext
just as your error tells you.
{
public UsageOfEntity()
{
var context = new Context();
var entity = new Entity();
int result = entity.ExampleMethod(context);
}
}
You are trying to pass Context
to IContext
in this line
entity.ExampleMethod(context);
You should make the Type
passed in ExampleMethod()
Context<FooBar>
.
I would also like to point out that making an interface for a POCO
class is unnecessary, just keep it a normal class.
Your code should look like this:
class Entity : IEntity
{
public int ExampleMethod(Context<FooBar> context)
{
return context.FooBar.Value;
}
}
interface IEntity
{
int ExampleMethod(IContext<IFooBar> context);
}