0

Consider the following:

class ControllerFactoryBase<P> : where P : PledgeReadOnly
{
    public void Foo()
    {
         PledgeRepositoryReadOnly<P> repos = PledgeRepository();
         new AdminController(repos); // compilation error here
    }
}

public interface PledgeRepositoryReadOnly<out P> where P : PledgeReadOnly
{
    IEnumerable<P> GetPledgesToBeneficiary();

}

public class AdminController
{
    public AdminController(PledgeRepositoryReadOnly<PledgeReadOnly> pledgeProvider)
    { ... }
}

I'm getting a compilation error on the instantiation of AdminController with message:

cannot convert from 'PledgeRepositoryReadOnly<P>' to 'PledgeRepositoryReadOnly<PledgeReadOnly>'

and I'm not sure why. I believe this substitution is safe. Can you help me understand why it is not?

edit more digestible presentation: http://csharppad.com/gist/9283391

Dejas
  • 3,511
  • 4
  • 24
  • 36
  • @chenZ - replacing 'out' with 'in' causes a compilation error on PledgeRepositoryReadOnly. – Dejas Feb 28 '14 at 06:24
  • yes,i try your code,it can compile,no error – chenZ Feb 28 '14 at 06:38
  • can you paste PledgeRepository() ? – chenZ Feb 28 '14 at 06:39
  • @chenZ That method is actually abstract, but sure ' protected abstract PledgeRepository

    PledgeRepository();' I argue this is irrelevant though because there is no error on the repos assignment line.

    – Dejas Feb 28 '14 at 06:43
  • is PledgeRepository like 'class PledgeRepository

    : PledgeRepositoryReadOnly

    where P : PledgeReadOnly',i use this,and everything is ok

    – chenZ Feb 28 '14 at 07:07
  • @chenZ almost. I've uploaded the code in a more digestible format at: csharppad.com/gist/9283391 – Dejas Mar 01 '14 at 01:25
  • @chenZ does the code I provided in the csharpapd link compile for you? If so, what version of csc are you using? – Dejas Mar 01 '14 at 02:10
  • i got a same err with your code,if PledgeReadOnly is a class,that's ok.interface,err. – chenZ Mar 01 '14 at 13:58
  • or,change all where P:PledgeReadOnly to where P:class,PledgeReadOnly – chenZ Mar 01 '14 at 14:00
  • Relevant thread: http://stackoverflow.com/questions/12454794/why-covariance-and-contravariance-do-not-support-value-type – Dejas Mar 03 '14 at 05:08

1 Answers1

1

with some step,finaly,i get what's wrong
first

public interface PledgeReadOnly
{

}

this is a interface,and

where P : PledgeReadOnly

it mean p must be a PledgeReadOnly but

public struct x : PledgeReadOnly
{
}

public class y : PledgeReadOnly
{
}

both class and struct and implement from a interface not sure P is a class or a struct you can change your PledgeReadOnly from interface to class or you can change all

where P : PledgeReadOnly

to

where P : class,PledgeReadOnly

it make sure P is a class

chenZ
  • 920
  • 4
  • 16