C # Generics - вернуть список с типом, зависящим от параметра. - PullRequest
0 голосов
/ 08 мая 2018

Полное раскрытие, я не полностью понимаю дженерики, но надеюсь, что ответ на этот вопрос прояснит ситуацию.

У меня есть приложение, которое позволяет пользователю создавать собственные запросы. Запрос будет использовать Entity Framework. Я хотел бы вернуть список результатов, тип которых зависит от того, какой столбец они запрашивали. Другими словами, мне нужен метод, который может иметь несколько типов возврата. Я получаю тип, используя отражение в столбце, а затем хотел бы перейти к этому методу.

    public static T getValues<T>(string ColName, Type type)
    {
        var result = db.AC_PROPERTY.Select(ColName);

        if (type == typeof(string))
        {
            List<string> list = new List<string>();
            //Query and add results to list. 
            return list;

        }

        if (type == typeof(double?) || type == typeof(double))
        {
            List<double> list = new List<double>();
            //Query and add results to list. 
            return list;

        }

        if (type == typeof(int) || type == typeof(int?))
        {
            List<int> list = new List<int>();
            //Query and add results to list. 
            return list;
        }

        if (type == typeof(DateTime))
        {
            List<DateTime> list = new List<DateTime>();
            //Query and add results to list. 
            return list;

        }
    }

Я получаю сообщение о том, что не могу неявно преобразовать Список (или соответствующий тип) в T.

Может кто-нибудь объяснить это и, возможно, рассказать мне, как это сделать.

1 Ответ

0 голосов
/ 08 мая 2018

Задайте себе вопрос: как T и Type type значимо различаются? Зачем вам оба?

Вы не.

Кроме того, хотя технически возможно проверить тип универсального параметра, вам не следует этого делать. Это кодовый запах. Если ваш метод универсален, тело метода также должно быть универсальным. Это включает в себя отсутствие необходимости знать точное значение T.

1. Избавиться от Type type

public static List<T> getValues<T>(string ColName)
{
    //...
}

Обратите внимание, как будет использоваться этот метод:

List<DateTime> myDateList = getValues<DateTime>("MyDateTimeColumn");

2. Сделайте тело метода общим

public static List<T> getValues<T>(string ColName)
{
    List<T> myReturnList = new List<T>();
    var selectedColumnValues = db.AC_PROPERTY.Select(ColName);

    //Query and add results to list. 

    return myReturnList;
}

Выглядит намного аккуратнее, не так ли? Я заметил, что вы пропустили фактическое создание списка; поэтому я тоже опустил это сейчас.


Я мог бы перейти к остальной части тела метода, основываясь на некоторых предположениях, но здесь есть гораздо более важное соображение.

Ваш метод, похоже, ничем не отличается от Метод LINQ's Select () !

Так что вместо того, чтобы делать это с помощью пользовательского метода getValues<T>:

List<DateTime> myDateList = getValues<DateTime>("MyDateTimeColumn");

Вы можете использовать существующий метод LINQ:

List<DateTime> myDateList = myDataList.Select(item => item.MyDateTimeProperty).ToList();

(Примечание: ToList() может быть необязательным, но рекомендуется из-за ленивой оценки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...