【问题标题】:Extension method with nested generics具有嵌套泛型的扩展方法
【发布时间】:2015-03-22 19:19:49
【问题描述】:

我在一个多语言网站上工作,我已经为我的“可本地化”实体构建了这个结构。

接口:

public interface ILocalizable<T>
    where T : ILocalized
{
    ICollection<T> Content { get; set; }
}

public interface ILocalized
{
    int LanguageId { get; set; }
    virtual Language Language { get; set; }
}

及实施:

public class Entity : ILocalizable<EntityLocalized>
{
    public int Id { get; set; }
    public ICollection<EntityLocalized> Content { get; set; }
}

public class EntityLocalized : ILocalized
{
    public int LanguageId { get; set; }
    public virtual Language Language { get; set; }

    public int EntityId { get; set; }
    public string Title { get; set; }
}

这样做的原因是我可以编写一个扩展方法,让我可以通过这种方式获取正确的字符串:

Entity entity; // get entity from database
string localizedString = entity.Content.Translate(localized => localized.Title);

一切正常。我只是想编写另一个扩展方法,这样可以在构建查询时节省一些工作。这样我就不用一直写了:

IQueryable<Entity> query; // some query
return query.Include(entity => entity.Content.Select(localized => localized.Language));

所以我有这个:

public static IQueryable<TEntity> WithLocalization<TEntity>(this IQueryable<TEntity> query)
{
    return query.Include(entity => entity.Content.Select(content => content.Language));
}

但显然我需要指定泛型类型。这不会编译。我什么都试过了。

public static IQueryable<TEntity> WithLocalization<TEntity>(this IQueryable<ILocalizable<ILocalized>> set) where TEntity : ILocalizable<ILocalized> {}

IQueryable<Entity> query; // get query
query.WithLocalization(); // intellisense doesn't display and this won't compile

我有点理解原因。那里已经讨论过很多次了。我只是想知道是否有一种方法可以构建这样的扩展方法而无需显式使用和传递 2 个泛型类型,例如:

public static IQueryable<TEntity> WithLocalization<TEntity, TEntityLocalized>(this IQueryable<TEntity> set)           
    where TEntityLocalized : ILocalized
    where TEntity : ILocalizable<TEntityLocalized> {}

谢谢!

【问题讨论】:

  • 只是好奇,为什么要使用 virtual 表示 Language 属性。具体的类会被继承吗?

标签: c# generics extension-methods


【解决方案1】:

我想你想要...

public static IQueryable<ILocalizable<TEntityLocalized>> WithLocalization<TEntityLocalized>(this IQueryable<ILocalizable<TEntityLocalized>> query)
    where TEntityLocalized : ILocalized {
    return query.Include(entity => entity.Content.Select(content => content.Language));
}

【讨论】:

  • 它对我不起作用。在这种情况下,我收到错误:无法将类型 'IQueryable>' 隐式转换为 'Entity'
  • 作为运行时异常?
  • 这没有意义。无论 T 是什么,您都无法将 IQueryable&lt;T&gt; 转换为 T
  • 对不起,我没有写对。它是:IQueryable> 到 IQueryable
  • 这仍然没有意义。你能告诉我们你的电话号码吗?
【解决方案2】:

您没有将TEntity 泛型参数正确传播到签名中。

public static IQueryable<ILocalizable<TEntity>> WithLocalization<TEntity>(this IQueryable<ILocalizable<TEntity>> query)
    where TEntity : ILocalized
  {
      return query.Include (entity => entity.Content.Select (content => content.Language));
  }

public class Test
{
   public Test()
   {
      IQueryable<Entity> query;
      query.WithLocalization ();
   }
}

正确编译并给出正确的智能感知。

【讨论】:

    猜你喜欢
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 2015-07-19
    相关资源
    最近更新 更多