Generic interface member

F

ffimbel

Hi,

Today I ran into an issue using interface and generic list.
Here is a sample of code to illustrate the issue.

I have two interfaces and two concrete classes (simplifed for sake of
simplicity)

public interface IField
{
String Name
{ get;}
}

public interface IStructure
{
IList<IField> Fields{get;}
}


public class FillerField: IField
{
private String _name;

public String Name
{
get { return _name; }
set { _name= value; }
}
}

public class FillerStructure:IStructure
{
private IList<FillerField> _fields;

public IList<FillerField> Fields
{
get { return _fields; }
set { _fields = value; }
}
}

When I try to compile I get an error stating that FillerStructure
doesnt implement
IStructure interface.
If I change public IList<FillerField> Fields method signature to it's
interface based public IList<IField> Fields it works.
Any idea why it's preventing to compile in the first place ?

Thanks in advance for your help
 
J

Jon Skeet [C# MVP]

If I change public IList<FillerField> Fields method signature to it's
interface based public IList<IField> Fields it works.
Any idea why it's preventing to compile in the first place ?

Yes - generic types don't support covariance; a List<string> is not
convertible to a List<object>. Here's why:

List<string> x = new List<string>();
List<object> o = x;
o.Add(new object());
string s = x[0];


Now, unless the second line fails to compile (as it does now) that will
build successfully - and fail at runtime. Generics is designed to go as
far as possible towards preventing runtime cast exceptions etc.
 
F

ffimbel

Thanks it makes sense now.



If I change public IList<FillerField> Fields method signature to it's
interface based public IList<IField> Fields it works.
Any idea why it's preventing to compile in the first place ?

Yes - generic types don't support covariance; a List<string> is not
convertible to a List<object>. Here's why:

List<string> x = new List<string>();
List<object> o = x;
o.Add(new object());
string s = x[0];

Now, unless the second line fails to compile (as it does now) that will
build successfully - and fail at runtime. Generics is designed to go as
far as possible towards preventing runtime cast exceptions etc.
 
C

Christof Nordiek

I have two interfaces and two concrete classes (simplifed for sake of
simplicity)

public interface IStructure
{
IList<IField> Fields{get;}
}

public class FillerStructure:IStructure
{
private IList<FillerField> _fields;

public IList<FillerField> Fields
{
get { return _fields; }
set { _fields = value; }
}
}

When I try to compile I get an error stating that FillerStructure
doesnt implement
IStructure interface.
If I change public IList<FillerField> Fields method signature to it's
interface based public IList<IField> Fields it works.
Any idea why it's preventing to compile in the first place ?

According to interface mapping rules a property must have identical type as
the interface property it implements.

So even if IList<FillerField> could be cast implicitly to IList<IField>
(wich does not, see post of Jon), the property FillerStructure.Fields
wouldn't map to IStructure.Fields.

Christof
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top