【问题标题】:How do I return a class that inherits a generic list?如何返回继承通用列表的类?
【发布时间】:2011-09-30 13:14:57
【问题描述】:

我有这门课:

public class CampaignMaps : List<CampaignMap> { };

CampaignMap 对象是我自己的,不继承任何东西。它有你的标准属性和方法。

然后我有一个 CampaignMapAdapter 对象,它充当我的 ObjectDatasource 的数据。它有一个数据私有属性:

[DataObject(true)]
public class CampaignMapAdapter
{
  private Database db = new Database(
  ConfigurationManager.AppSettings["AppName"],
  ConfigurationManager.AppSettings["DBService"],
  ConfigurationManager.AppSettings["DBUser"]);

  private CampaignMaps _data
  {
    get 
    {
      CampaignMaps maps = new CampaignMaps();
      CampaignsAdapter adapter = new CampaignsAdapter();
      db.Init();
      db.AddParameter(null, null, ParameterDirection.ReturnValue, OracleType.Cursor);
      DataSet ds = db.ExecuteDataSet(PROC_GET_CAMPAIGN_MAPS);
      DataTable dt = ds.Tables[0];
      foreach (DataRow row in dt.Rows)
      {
        CampaignMap campaignMap = new CampaignMap();
        //populate the campaignMap object...
        maps.Add(campaignMap);
      }
      return maps;
    }
    set 
    {
      _data = value;
    }
  }

  [DataObjectMethod(DataObjectMethodType.Select, true)]
  public CampaignMaps GetFiltered(bool hasErrors)
  {
    var selectQuery = from c in _data where c.HasError == hasErrors select c;
    _data = selectQuery;
  }
}

_data = selectQuery; 抛出错误:

不能隐式转换类型 'System.Collections.Generic.IEnumerable' 到 '活动地图'。存在显式转换(您是否缺少 演员?)

我想用简单的英语我希望 _data 始终包含 ALL 我的数据元素,然后调用特定的 select 应该根据需要减少它们。我该怎么做?

提前致谢。

【问题讨论】:

  • 你在 CampaignMaps 中做一些特定的事情吗?使用它而不仅仅是 List&lt;CampaignMap&gt; 会使这变得更加困难。
  • 为什么需要这样的课程?为什么你不能返回一个List&lt;CampaignMap&gt; 对象,或者创建一个带有List&lt;CampaignMap&gt; 字段的类。

标签: c# asp.net .net-3.5 linq-to-objects


【解决方案1】:

好吧,你可以这样做:

CampaignMaps maps = new CampaignMaps();
maps.AddRange(selectQuery);
_data = maps;

这将为您提供正确类型的正确数据。

但是,我强烈认为 不是List&lt;T&gt; 派生的开始 - 这几乎不是一个好主意;除非您真的专门研究行为,否则更喜欢组合而不是继承。

我还要说,在名为 GetFiltered 的方法中改变 current 对象违反了最小意外原则。我会或者对其进行更改以使其更清楚地表明它是一个突变(例如“FilterByErrors”)并给它一个void返回类型,只是让它返回过滤后的列表而不改变当前对象。

【讨论】:

    【解决方案2】:

    你为什么要_data = selectQuery;

    我认为您在 GetFiltered 方法中的意图类似于:

    return new CampaignMaps(selectQuery);
    

    但是,就像亚当所说的那样,我会认真考虑您为什么要使用 CampaignMaps 类。

    如果您希望公共接口只允许通过“HasErrors”进行过滤,则使 GetFiltered 方法如下所示:

    public IEnumerable<CampaignMap> GetFiltered(bool hasErrors)
    {
        return _data.Where(c => c.HasError == hasErrors);
    }
    

    我看不出有什么理由让您一开始就想要使用这个 GetFiltered 方法。为什么不将 _data 属性公开为仅获取的 IEnumerable&lt;CampaignMap&gt;,然后允许其他对象直接在其上运行 Linq 查询?像这样:

    public IEnumerable<CampaignMap> Data
    {
        get { return _data; }
    }
    

    然后我可以在其他地方写Data.Where(c =&gt; c.HasError == whatever)

    【讨论】:

    • 我想我的结构有点复杂。我接受了你和每个人的建议,并一起取消了 CampaignMaps 类,只制作了 List 或 IEnumerable 的所有内容,它可以全面发挥作用。
    猜你喜欢
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多