如何将列表<t>转换为列表<classname>

时间:2015-09-28 14:24:53

标签: c# generics

我使用通用方法来填充所有类型的下拉列表

下面是我的代码。

实体类型如下

public class Role
{
    public string Id { get; set; }
    public string Name { get; set; }
}

public class DropDown
{
    public string Id { get; set; }
    public string Name { get; set; }
}

我能够在
成功获取数据 var data = DataFetcher.FetchData<T>();

private static void Main( string[] args )
{
    List<DropDown> cities = BLL.GetDataList<City>();
    List<DropDown> states = BLL.GetDataList<State>();
    List<DropDown> roles = BLL.GetDataList<Role>();
}

public static class BLL
{
    public static List<DropDown> GetDataList<T>() where T : class ,new()
    {
        var data = DataFetcher.FetchData<T>();
        return data as List<DropDown>;
    }
}

我知道这个演员data as List<DropDown>会失败,这就是为什么它将null返回给调用方法,

如何将通用列表转换为已知类型列表?

3 个答案:

答案 0 :(得分:3)

您必须问自己:我如何将T转换为DropDown?如果你不能回答这个问题,答案是:你不能。

猜测您的DropDown类有object Value属性,其中包含下拉值,您希望将数据实体分配给该属性。

然后您可以将数据实体列表投影到DropDown,如下所示:

var data = DataFetcher.FetchData<T>();
return data.Select(d => new DropDown { Value = d }).ToList();

至于您的修改:因此您至少有一种类型,即显示的Role,具有IdName属性。但是T类型并不能保证这一点,因此您需要引入一个界面:

public interface INamedIdentifyableEntity
{
    string Id { get; set; }
    string Name { get; set; }
}

并将其应用于您的实体。然后将其作为通用约束引入并进行映射:

return data.Select(d => new DropDown
{ 
    Id = d.Id,
    Name = d.Name,
}).ToList();

但是你不想要这个,因为在这里你将这两个属性绑定到下拉列表。明天您需要一个Code而不是IdText而不是Name的实体,因此您必须添加更多接口,更多重载等等。

相反,您可能希望使用反射,您可以在其中指定调用中的成员名称:

List<DropDown> cities = BLL.GetDataList<City>(valueMember: c => c.CityCode, displayMember: c => c.FullCityname);

并使用这些成员表达式查找data的值并将其填入DropDown

但是,你要重新发明轮子。完全忽略你的DropDown课程,并将下拉代留给前端,在本例中为MVC:

var cities = DataFetcher.FetchData<City>();

var selectList = new SelectList(cities.Select(c => new SelectListItem
{
    Selected = (c.Id == selectedCityId),
    Text = c.FullCityName,
    Value = c.CityCode,
});

或者:

var selectList = new SelectList(cities, "CityCode" , "FullCityName", selectedCityId);

答案 1 :(得分:1)

一种解决方案是使用AutoMapper

首先在模型之间创建一个这样的地图:

AutoMapper.Mapper.CreateMap<Role, DropDown>();

如果需要,请对CityState类执行相同的操作。

然后您可以使用AutpMapper将对象转换为DropDown,如下所示:

public static List<DropDown> GetDataList<T>() where T : class ,new()
{
    var data = DataFetcher.FetchData<T>();
    return data.Select(x => AutoMapper.Mapper.Map<DropDown>(x)).ToList();
}

答案 2 :(得分:0)

如果我正确理解了这个问题,你可以按如下方式使用Linq。

return data.Cast<DropDown>().ToList();