1

I am using EF code first to generate my db and I do need concrete property for ICollection of EF entity models. I am writing a data access layer ( Using generic classes) however hit the following road block with using interfaces in my generic class as shown below.

public interface ITestClassProp
{
    int Value { get; set; }
}

public class TestClassProp : ITestClassProp
{
    public int Value { get; set; }
}


public interface ITestClass
{
    ICollection<ITestClassProp> TestProp { get; set; }
}

public class TestClass : ITestClass
{
    // works
    //public ICollection<ITestClassProp> TestProp { get; set; }
    // does not work
    public ICollection<TestClassProp> TestProp { get; set; }
}

Am I totally mis using the interfaces? why cant I use TestClassProp instead of ITestClassProp?

Thanks

3
  • Because you are redefining the interface. If you want to use concrete types, you have to define it in the interface. Commented Jun 9, 2015 at 19:42
  • Because the ITestClass interface has a property of type ICollection<ITestClassProp>. You aren't implementing the interface if your is a ICollection<TestClassProp> Commented Jun 9, 2015 at 19:43
  • You could make this a generic interface ITestClass<T> where T : ITestClassProp. Then TestClass : ITestClass<TestClassProp>. Commented Jun 9, 2015 at 19:45

3 Answers 3

3

When you implement an interface, you have to implement the methods/properties of that interface with the same signature. Since the interface declares ICollection<ITestClassProp> TestProp { get; set; } then your TestClass must also declare ICollection<TestClassProp> TestProp { get; set; }.

The reason this is necessary is that other classes that know about the interface but not the concrete class are expecting the property to be ICollection<ITestClassProp> and not ICollection<TestClassProp>.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Mason. I appreciate your answer. i have mark david L as answer as that is how I end up solving the problem and might be useful for others who are looking for quick solutions. Thanks again.
0

As you've currently written your code, you are not satisfying the requirement you've imposed via your ITestClass interface, which is to have a property of ICollection<ITestProp>.

One way around this is to actually make ITestClass generic, but provide a generic constraint of ITestClassProp

public interface ITestClassProp
{
    int Value { get; set; }
}

public class TestClassProp : ITestClassProp
{
    public int Value { get; set; }
}


public interface ITestClass<T> where T : ITestClassProp
{
    ICollection<T> TestProp { get; set; }
}

public class TestClass : ITestClass<TestClassProp>
{
    public ICollection<TestClassProp> TestProp { get; set; }
}

This allows you to provide any concrete type that implements ITestProp to your ICollection.

1 Comment

I end up solving with the generic class as you shown here. Thanks again.
0

Simply, the interface declares a property of type ICollection, but you implement it as ICollection, which has a totally different signature.

You might want to read up on covariance and contravariance also.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.