Be.St.
Be.St.

Reputation: 4181

Cannot convert from 'SpecificComponent' to 'IComponent<IComponentGuid>'

I've this class structure:

namespace ClassLibrary1
{
    public interface IComponentGuid { }

    class ComponentGuid : IComponentGuid{}

    internal interface IComponent<T> where T : IComponentGuid {
         List<T> List();
     }

    class SpecificComponent : IComponent<ComponentGuid> { 
      public List<ComponentGuid> List()
      {
          throw new System.NotImplementedException();
       }
    }

    class P
    {
        public P(IComponent<IComponentGuid> pComponent) { }
    }


    class Caller
    {
        public Caller()
        {
            var specific = new SpecificComponent();

            var p = new P(specific);
            }
    }
}

The problem arise instantiating P: var p = new P(specific);

I get a

cannot convert from 'ClassLibrary1.SpecificComponent' to 'ClassLibrary1.IComponent<ClassLibrary1.IComponentGuid>'

What am I doing wrong?

Thank you.

Upvotes: 2

Views: 76

Answers (2)

Be.St.
Be.St.

Reputation: 4181

I'm trying this solution splitting the IComponent interface into two, one covariant and one invariant.

namespace ClassLibrary1
{
    public interface IComponentGuid { }

    public class ComponentGuid : IComponentGuid { }

    public interface IComponentBase<out T> where T : IComponentGuid
    {
        IEnumerable<T> List();
    }

    interface IComponent<T>
    {
        void AddToList(T item );
    }

    public class SpecificComponent : IComponentBase<ComponentGuid>, IComponent<ComponentGuid>
    {
        public IEnumerable<ComponentGuid> List()
        {
            throw new System.NotImplementedException();
        }

        public void AddToList(ComponentGuid item)
        {
            throw new System.NotImplementedException();
        }
    }


    public class P
    {
        public P(IComponentBase<IComponentGuid> pComponentBase) { }
    }


    class Caller
    {
        public Caller()
        {
            var specific = new SpecificComponent();

            var p = new P(specific);

        }
    }
}

Upvotes: 0

Jesse C. Slicer
Jesse C. Slicer

Reputation: 20157

You can make it work if you forgo List<T> on your interface and replace it with a co-variant interface of IEnumerable<T> and then make your type parameter co-variant as well:

namespace ClassLibrary1
{
    public interface IComponentGuid { }

    class ComponentGuid : IComponentGuid{}

    internal interface IComponent<out T> where T : IComponentGuid {
         IEnumerable<T> List();
     }

    class SpecificComponent : IComponent<ComponentGuid> { 
      public IEnumerable<ComponentGuid> List()
      {
          throw new System.NotImplementedException();
       }
    }

    class P
    {
        public P(IComponent<IComponentGuid> pComponent) { }
    }


    class Caller
    {
        public Caller()
        {
            var specific = new SpecificComponent();

            var p = new P(specific);
            }
    }
}

Upvotes: 1

Related Questions