Отправка пустого класса в универсальный класс в качестве параметра по умолчанию в C#

#c#

#c#

Вопрос:

У меня есть QueryFilter<TSearchFilter> класс (см. Ниже). И я создал QueryFilter класс, который наследуется от этого класса. В настоящее время я использую QueryFilter без указания типа, вот так:

 var queryFilter = new QueryFilter();
  

Чтобы сделать это, я создал поддельный EmptySearchFilter класс для достижения этой цели. Это работает отлично; никаких проблем.

 public class QueryFilter<TSearchFilter> where TSearchFilter : class
{
    public QueryFilter()
    {
        SearchFilter = (TSearchFilter)Activator.CreateInstance(typeof(TSearchFilter));
    }
    public string SortBy { get; set; }
    public int PageFirstIndex { get; set; }
    public byte PageSize { get; set; }
    public TSearchFilter SearchFilter { get; set; }
}

public class QueryFilter : QueryFilter<EmptySearchFilter> { }

public class EmptySearchFilter { }
  

Но, я думаю, что, вероятно, есть способ избежать использования этого поддельного класса ( EmptySearchFilter ), выполнив что-то вроде:

 public class QueryFilter : QueryFilter<typeof(Class)>{ }
  

Есть ли способ сделать это?

Комментарии:

1. В большинстве случаев с парой общих / неродовых типов, которые соответствуют одной и той же концепции, неродовой класс является базовым классом, производным от общего. Но незнание того, как эти типы используются , затрудняет предоставление каких-либо конкретных советов.

2. Я думаю, вы хотите сказать, как в ответе @ZoharPeled. Я прав?

Ответ №1:

Вы можете изменить цепочку наследования следующим образом:

 public class QueryFilter 
{ 
    public string SortBy { get; set; }
    public int PageFirstIndex { get; set; }
    public byte PageSize { get; set; }
}

public class QueryFilter<TSearchFilter> : QueryFilter 
    where TSearchFilter : class, new() 
{
    public QueryFilter()
    {
        SearchFilter = new TSearchFilter();
    }
    public TSearchFilter SearchFilter { get; set; }
}
  

Таким образом, QueryFilter не нужно использовать поддельный класс.

Кроме того, я добавил new() ограничение, чтобы избавиться от Activator.CreateInstance вызова.

Комментарии:

1. Спасибо @ZoharPeled. Эта структура лучше меня. Итак, я конвертирую свой класс, подобный вашему, но в моем методе public static async Task<GridResult<List<T>>> GetGridResult<T, TSearchFilter>(this IQueryable<T> query, QueryFilter<TSearchFilter> queryFilter) where TSearchFilter : class {} выдается ошибка типа TSearchFilter’ должен быть неабстрактным типом с общедоступным конструктором без параметров, чтобы использовать его в качестве параметра ‘TSearchFilter’ в универсальном типе или методе ‘QueryFilter<TSearchFilter>’

2. Это из-за new() ограничения. Попробуйте удалить его и вместо этого вернуться к Activator.CreateInstance и посмотреть, не выдаст ли это исключение.

3. Что я должен добавить Activator.CreateInstance в структуру вашего класса @ZoharPeled

4. заменить SearchFilter = new TSearchFilter(); на SearchFilter = (TSearchFilter)Activator.CreateInstance(typeof(TSearchFilter));

5. Мой код сейчас не создается. Потому что мой метод public static async Task<GridResult<List<T>>> GetGridResult<T, TSearchFilter>(this IQueryable<T> query, QueryFilter<TSearchFilter> queryFilter) where TSearchFilter : class {} хочет использовать QueryFilter<TSearchFilter> . Но в вашей структуре классов мы отправляем QueryFilter @ZoharPeled