2014-11-15 70 views
0

我是接口新手。需要一个接口的c#方法?

我有很多对象作为DTO通过我的图层传递给UI。其中一些非常复杂(很多属性),但我只想在某些情况下在DropDown列表中使用它们。这些DTO全部具有int Idstring Description

我想创建一个静态函数,它接受这些对象之一的List<>,并返回一个List<SelectListItem>

所以,我尝试使用接口的第一次。

我创建了一个接口:

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

然后,我分配了接口,我的DTO对象之一,我想转换:

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>(); 
    } 
} 

然后,我创建了通用的方法需要列出类别dtos,并希望返回列表

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; 
} 

但是,当我尝试使用这个方法,将它传递给List,它失败了。

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

GetCategoriesByPortfolioId返回一个列表。

它的失败与错误:

CategoryDto is not assignable to IListableItem

这也可能是我的一个基本的了解的接口问题,但我在做什么错了,我怎么能解决这个问题?

+0

'MyService.GetCategoriesByPortfolioId()'返回的类型是什么? – Dirk

回答

5

如果您的方法预计为List<IListableItem>,则无法通过List<CategoryDTO>

如果有可能,你可以Add实现该接口IListableItem成持有CategoryDTO元素的集合,而读他们的元素不同实例。

最终,这是没有意义的。

如果您使用IEnumerable接口,您可以修复它。这允许covariance(going from higher type to lower type in generic type parameter)

它的工作原理的原因,是IEnumerable是集合的“只读视图”,所以你不能真正添加​​任何东西给它 - 以及什么是最重要的type parameter标记

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

*它应该是理论上有效的*:它只对只读集合有效,但不是一般。这就是为什么可以用IEnumerable来完成的原因。 – Dirk

+0

谢谢克里斯!这解决了它。我不知道为什么。需要阅读,但谢谢。 – Craig

+1

@克雷格一个'清单'不能投入'清单',因为你可以添加一个'香蕉'到'清单'。 – Dirk

相关问题