0

I'm having issues trying to use a list of interfaces. (I'm probably terrible at explaining this, I've only been coding for a year now, but here goes.)

I have an interface:

public interface IComboBoxItem
{
    string Display { get; set; }
    int? IntValue { get; set; }
    string StringValue { get; set; }
}

And a class that implements that interface:

public class GenericComboBoxItem : IComboBoxItem
{
    public virtual string Display { get; set; }
    public virtual int? IntValue { get; set; }
    public virtual string StringValue { get; set; }

    public GenericComboBoxItem(string stringValue)
    {
        Display = stringValue;
        StringValue = stringValue;
        IntValue = null;
    }
}

Then I take a list of these in my View Model's constructor:

public class TransactionModalVM
{
    public TransactionModalVM(List<IComboBoxItem> categoryList)
    {
        CategoryList = categoryList;
    }

    public List<IComboBoxItem> CategoryList { get; set; }
}

Yet when I attempt to pass them in

public class TransactionsOM
{
    internal TransactionModalVM GetTransactionModalVM()
    {
        return new TransactionModalVM(new List<GenericComboBoxItem>() { new GenericComboBoxItem("Not yet Implemented") });
    }
}

I get an error that it can't convert from List<GenericComboBoxItem> to List<IComboBoxItem>.

I originally ran into this when I was using a class that inherited from GenericComboBoxItem and thought I just had to use and interface instead of inheritance but then found that both classes failed and figured there but be some trick I'm missing here.

This may possibly be a duplicate of something, but I've spent the morning searching with no luck and thought I'd post a new question.

Much appreciation in advance for any help!

JakeB
  • 153
  • 2
  • 9
  • Take a look at generic covariance and contravariance in C# – Yair Halberstadt Nov 25 '18 at 20:24
  • As specified by `public TransactionModalVM(List categoryList)`, _TransactionModalVM_ wants a list that can contain **any** type of _IComboBoxItem_ elements. Yet you try to provide a list that can **only** contain _GenericComboBoxItem_ elements. Kaboom! Make _TransactionModalVM_ happy by creating a `new List() { new GenericComboBoxItem(...) }` in your _GetTransactionModalVM_ method. –  Nov 25 '18 at 20:26
  • oh! Thanks @elgonzo!! – JakeB Nov 25 '18 at 20:29

1 Answers1

0

It would be a good idea to research covariance and contravariance in C#.

However in your particular case,using an IReadOnlyList instead of a list in your view model would solve your problem.

public class TransactionModalVM
{
    public  TransactionModalVM(IReadOnlyList<IComboBoxItem> categoryList)
    {
        CategoryList = categoryList;
    }

public IReadOnlyList<IComboBoxItem> CategoryList { get; set; }
}

A List<GenericComboBoxItem> is convertible to an IReadOnlyList<IComboBoxItem>, but not to a List<IComboBoxItem>

Yair Halberstadt
  • 5,733
  • 28
  • 60