使用泛型类属性转换继承的类

时间:2014-10-09 00:29:03

标签: c# generics

IListModel公开了一个名为Items of Abstract type ListItemModel的通用列表属性。但是当我尝试将任何派生类转换为IListModel时,我得到了#34;对象引用未设置为对象的实例"错误。

public abstract class ListItemModel
{
    public string UserName { get; set; }
    public string SomeProperty { get; set; }
}

public interface IListModel<T> where T : ListItemModel
{
    List<T> Items { get; set; }
}

public class UserListModel : IListModel<UserListItemModel>
{
    public string Query { get; set; }
    public int TotalUsers { get; set; }

    public List<UserListItemModel> Items { get; set; }
}

public class UserListItemModel : ListItemModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

var users = new UserListModel
{
    Query = "a",
    TotalUsers = 1111,
    Items = new List<UserListItemModel>
    {
        new UserListItemModel {FirstName = "a", LastName = "b"}
    }
};

// later in the application users will be passed around as an object which 
// must cast it to  IListModel<ListItemModel> in order to access its properties
// but converted will return null
var converted = users as IListModel<ListItemModel>;


foreach (var item in converted .Items)
{
    item.SomeProperty = DoSomethingHere(item.UserName);
}

我在这里想要实现的是能够从ListItemModel基类填充SomePropery。

3 个答案:

答案 0 :(得分:1)

创建通用列表项引用接口:

public interface IListItemModel
{
    List<ListItemModel> Items { get; }
}

让您的类使用显式构造函数实现:

List<LIstItemModel> IListModel.Items
{
  get { return this.Items; }
}

然后您可以将用户转换为IListModel。

答案 1 :(得分:1)

请参阅:as (C# reference)

  

但是,如果无法进行转换,则返回null而不是引发异常。

基本上,正在发生的是你正在进行无效的演员表,而且无效演员表的结果取决于所使用的演员表格。

var converted = users as IListModel<ListItemModel>; // converted is null
var converted = (IListModel<ListItemModel>)users;   // raises exception

铸造真的有必要吗? UserListModel : IListModel<UserListItemModel>似乎表明它是你想要的类型的IListModel,所以你应该只能将它提供给foreach块并从中工作,不是吗?

答案 2 :(得分:0)

感谢&#34; Brian Mains&#34;和&#34; Kyle Baran&#34;我的问题解决了。这是工作代码:

public abstract class ListItemModel
{
    public string UserName { get; set; }
}

public interface IListModel
{
    List<ListItemModel> ListItems { get; }
}

public abstract class BaseListModel<T> : IListModel where T : ListItemModel
{
    public List<T> Items { get; set; }

    public List<ListItemModel> ListItems
    {
        get { return Items.Cast<ListItemModel>().ToList(); }
    }
}

public class UserListModel : BaseListModel<UserListItemModel>
{
    public string Query { get; set; }
    public int TotalUsers { get; set; }
}

public class UserListItemModel : ListItemModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

var users = new UserListModel
{
    Query = "a",
    TotalUsers = 1111,
    Items = new List<UserListItemModel>
    {
        new UserListItemModel {FirstName = "a", LastName = "b"}
    }
};

// and finally I can cast the collection to IListModel
var converted = users as IListModel;


foreach (var item in converted .Items)
{
    item.SomeProperty = DoSomethingHere(item.UserName);
}