【问题标题】:How can I use LINQ with dynamic? Generics?如何将 LINQ 与动态一起使用?泛型?
【发布时间】:2017-08-09 07:42:05
【问题描述】:

我有这段代码:

public void RepeaterListato_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
    if (listType == "pages")
    {
        var item = (Pagina)e.Item.DataItem;
        BuildFoto(e, item, IDCategoriaImmaginiPacchettoOfferta);
    }
    else if (listType == "schede")
    {
        var item = (Scheda)e.Item.DataItem;
        BuildFoto(e, item, IDCategoriaImmaginiPacchettoOfferta);
    }
    else if (listType == "news")
    {
        var item = (New)e.Item.DataItem;
        BuildFoto(e, item, IDCategoriaImmaginiPacchettoOfferta);
    }
}

private void BuildFoto(RepeaterItemEventArgs e, dynamic item, string id)
{
    var immagine = item.Immagini.Cast<Allegato>().Where(p => p.Categoria == id).FirstOrDefault();
    if (immagine != null)
    {
        // ...
    }
}

所以,由于listType的类型(在Page_Load解决),item发生了变化,所以我使用dynamic。但 LINQ 不适用于 Cast 和 Where 动态分派操作。

有解决方法吗?我应该在您的意见中使用Generics 吗?最好的方法?

【问题讨论】:

  • 您能否提供一个显示问题的小型(完整)控制台应用程序,并与我们分享?这将使我们能够快速重现问题并为您提供一些解决方案。
  • Pagina、Scheda 和 New 是否继承自一个以 Immagini 作为属性的公共接口/基类? (如果为 true,item 参数可以是该类型,不需要动态)
  • 它们都继承自一个名为BrObject 的类。但是在BrObject 中没有Immagini 作为属性。
  • @markzzz 你能添加一个带有 Immagini 属性的接口并让它们实现吗?
  • @vc74:不。它们来自我无法编辑的 DLL。

标签: c# linq generics dynamic


【解决方案1】:

由于您无法访问 Pagina、Scheda 和 New 的源代码,因此您没有太多选择

一个是:

public void RepeaterListato_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
    IEnumerable<Immagini> immagini = null;

    switch (listType)
    {
      case "pages":
        immagini = ((Pagina)e.Item.DataItem).Immagini;
        break;

      case "schede":
        immagini = ((Scheda)e.Item.DataItem).Immagini;
        break;

      case "news":
        immagini = ((New)e.Item.DataItem).Immagini;
        break;
    }

    if (immagini != null)
    {
      BuildFoto(e, immagini, IDCategoriaImmaginiPacchettoOfferta);
    }
}

private void BuildFoto(RepeaterItemEventArgs e, IEnumerable<Immagini> immagini, string id)
{
    var immagine = immagini.Cast<Allegato>().Where(p => p.Categoria == id).FirstOrDefault();
    if (immagine != null)
    {
        // ...
    }
}

另一种选择是使用反射来获取 immagini 集合实例

还有一个选择是创建包装类:

public interface IImmaginiContainer
{
  IEnumerable<IImmagine> Immagini { get; }
}

public class NewWrapper : IImmaginiContainer
{
  public NewWrapper(New source)
  {
    _source = source;
  }
  private readonly New _source;

  public IEnumerable<IImmagine> Immagini => _source.Immagini;
}

// Create a similar class for Scheda and Pagina

private void BuildFoto(RepeaterItemEventArgs e, IImaginiContainer item, string id)
{
    var immagine = item.Immagini.Cast<Allegato>().Where(p => p.Categoria == id).FirstOrDefault();
    if (immagine != null)
    {
        // ...
    }
}

【讨论】:

  • 使用泛型?帮不上忙?
  • @markzzz 如果这 3 个类不继承自一个通用接口/基类,您将无法使用泛型,如果它们这样做了,您可以在 BuildFoto 中使用泛型约束
  • @markzzz 您还可以使用 Immagini 属性构建继承自共同祖先的包装类
  • 你能给我一个最后一个方法的例子吗?
猜你喜欢
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
  • 2022-11-02
  • 1970-01-01
相关资源
最近更新 更多