简体   繁体   中英

c# methods that takes an Interface?

I am new to Interfaces.

I have a lot of objects that I pass as DTOs through my layers to the UI. Some of them are quite complex (Quite a few properties), but I only want to use them, in certain circumstances, in DropDown lists. These DTOs all have an int Id , and a string Description .

I would like to create a static function that takes a List<> of one of these objects, and returns a List<SelectListItem>

So, I am trying to use Interfaces for the first time.

I created an Interface:

public interface IListableItem
{
    int Id { get; set; }
    string Description { get; set; }
}

And then, I assigned that interface to one of my DTO objects I am trying to convert:

public class CategoryDto : BaseDto , IListableItem
{
    public int PortfolioId { get; set; }
    public string Description { get; set; }
    public List<ExtendedSubCategoryDto> SubCategories { get; set; }
    public bool IsExpenseCategory { get; set; }

    public CategoryDto()
    {
        SubCategories = new List<ExtendedSubCategoryDto>();
    }
}

Then, I created my generic method that takes a list of the category dtos, and will hopefully return a list

public static List<SelectListItem> TranslateToSelectList(List<IListableItem> source)
{
    var reply = source.Select(item => new SelectListItem
    {
        Value = item.Id.ToString(CultureInfo.InvariantCulture), Text = item.Description
    }).ToList();

    return reply;
}

But, when I attempt to use this method, passing it a List, it fails.

    model.Categories =
        Translator.TranslateToSelectList(MyService.GetCategoriesByPortfolioId());

GetCategoriesByPortfolioId returns a List.

It's failing with the error:

CategoryDto is not assignable to IListableItem

It's probably a basic Interface understanding issue on my part, but what am I doing wrong, and how can I fix it?

If your method expects List<IListableItem> , you can't pass List<CategoryDTO> .

If that would be possible, you could Add different instances of elements that implement the interface IListableItem into a collection that is holding CategoryDTO elements, and read them.

Ultimately, that wouldn't make sense.

You can fix it, if you use IEnumerable interface. That allows covariance(going from higher type to lower type in generic type parameter) .

The reason it works, is that IEnumerable is a "read-only view" of collection, thus you can't really add anything to it - plus what's important, the type parameter is marked as covariant .

public static List<SelectListItem> TranslateToSelectList(
 IEnumerable<IListableItem> source)
{..}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM