如何投射列表< T>要列出< ClassName> [英] How to Cast List<T> To List<ClassName>

查看:105
本文介绍了如何投射列表< T>要列出< ClassName>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用泛型方法来填充所有类型的下拉列表。

下面是我的代码。

实体类型如下

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

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

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

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

public static class BLL
{
public static List< DropDown> GetDataList< T>()其中T:class,new()
{
var data = DataFetcher.FetchData< T>();
以List< DropDown>的形式返回数据;


我知道这个转换数据因为List< DropDown> 会失败,这就是为什么它将null返回给调用方法,



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

解决方案

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



I guess 你的 DropDown class有一个对象值属性,它包含下拉值,并且您希望将数据实体分配给该属性。



然后,您可以将数据实体列表投影到 DropDown s中:

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

至于编辑:至少有一种类型,显示角色,它具有 Id 名称属性。但是输入 T 并不能保证这一点,所以你需要引入一个接口:

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

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

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

但是你不需要这个,因为在这里你将这两个属性绑定到下拉菜单。明天你会想要一个 Code 代替 Id Text 的实体$ c>而不是名称,所以你必须添加更多的接口,更多的重载等等。



相反,您可能想使用反射,您可以在该调用中指定成员名称:

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


I am using generic method to fill my dropdown for all types

below is my code.

the entity type are as follow

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

i am able to fetch data successfully at
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>;
    }
}

I knew this cast data as List<DropDown> will fail,thats why its returning null back to calling method,

How can i cast Generic list to List of Known Type?

解决方案

You have to ask yourself: how do I want to convert T to DropDown? If you can't answer this, the answer is: you can't.

I guess your DropDown class has an object Value property, that holds the dropdown value, and you wish to assign the data entity to that property.

Then you can project the list of data entities to DropDowns as such:

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

As for your edit: so you have at least one type, the displayed Role, that has an Id and Name property. But type T doesn't guarantee this, so you'd need to introduce an interface:

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

And apply this to your entities. Then introduce it as a generic constraint and do the mapping:

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

But you don't want this, as here you are tying these two properties to dropdowns. Tomorrow you'll want an entity with Code instead of Id and Text instead of Name, so you'll have to add more interfaces, more overloads, and so on.

Instead you might want to use reflection, where you can specify the member names in the call:

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

And use these member expressions to look up data's values and fill those into the DropDown.

However, you're then reinventing the wheel. Leave out your DropDown class entirely, and leave the dropdown generation to the front end, in this case 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,
});

Or:

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

这篇关于如何投射列表&lt; T&gt;要列出&lt; ClassName&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆