Reputation: 1591
I have a generic class:
class JobDetails<IJobRequirement>{}
class SpecialRequirement: IJobRequirement{}
I'm unable to assign the values of type JobDetails<SpecialRequirement>
to variables of type JobDetails<IJobRequirement>
. Is this possible in C# or am I missing something basic ?
Upvotes: 0
Views: 120
Reputation: 2398
Generally Foo<A>
and Foo<B>
do not share a common ancestry. They share a common generic type definition, but that does not mean they are assignable even if public class B : A
.
You seem to be looking for Co- and Contravariance. A mechanism for generics in C# that lets you define compatibility between different types. However this only works for generic interfaces.
For example
public interface IJobDetails<out TRequirement>
where TRequirement : IJobRequirement
{
TRequirement Requirement { get; }
}
public class JobDetails<TRequirement> : IJobDetails<TRequirement>
{
public TRequirement Requirement { get; set; }
}
public void Test()
{
IJobDetails<IJobRequirement> a = new JobDetails<SpecificRequirement>();
}
However using the modifier in
or out
limits whether you can use the type only as a return value or a method argument.
This is the reason why you an assign IEnumerable<B>
to IEnumerable<A>
if public class B : A
because IEnumerable
is declared as IEnumerable<out T>
.
For further information I recommend reading the following Blog: http://tomasp.net/blog/variance-explained.aspx/
Upvotes: 5
Reputation: 1202
You can put constraints on Type Parameters:
interface IJobRequirement
{ }
class SpecialRequirement : IJobRequirement
{ }
class JobDetails<T> where T : IJobRequirement
{ }
Upvotes: 2