2015-01-23 4 views
1

Я работаю на многоязычном сайте, и я создал эту структуру для своих «локализуемых» объектов.Метод расширения с вложенными генериками

Интерфейсы:

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

Спасибо!

+0

просто любопытно, почему 'virtual' для языковой собственности. Являются ли конкретные классы наследуемыми? – ja72

ответ

0

Я думаю, что вы хотите ...

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)); 
} 
+0

Это не работает для меня. В этом случае я получаю сообщение об ошибке: Невозможно неявно преобразовать тип «IQueryable >» в «Entity» – Tacud

+0

В качестве исключения времени выполнения? –

+0

Во время компиляции. – Tacud

0

Вы не пропагандируя 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(); 
    } 
} 

правильно компилируется и дает правильный интеллект.

Смежные вопросы