Reputation: 18694
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?
Upvotes: 0
Views: 104
Reputation: 26268
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)
{..}
Upvotes: 5