создание универсального объекта с типом в качестве параметра функции в c # - PullRequest
1 голос
/ 20 марта 2019

Я пытаюсь создать универсальную функцию для анализа моего результата json с Newtonsoft:

private T ParseResult<T>(string queryResult)
{
    Result res = JsonConvert.DeserializeObject<Result>(queryResult);

    if (res.Success == 1)
    {
        try
        {
            return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(res.data));
        }
        catch (Exception)
        {
            return default(T);
        }
    }
    return default(T);
}

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

Моя проблема в том, что текущее решение возвращает пустое значение вместо пустого объекта. Как я могу добиться, чтобы возвращаемое значение никогда не было нулевым.

Ответы [ 3 ]

5 голосов
/ 20 марта 2019

Независимо от того, правильный это или неправильный подход.Проблема в том, что default(T) вернет по умолчанию для типа , для ссылочных типов , то есть null.Если вы хотите «пустой объект» (новый объект), вам придется использовать новое ограничение и new его (создать его экземпляр)

Пример

private T ParseResult<T>(string queryResult) where T : new()
{

    ...

    return new T();

}

Примечание : хотя есть предостережения

новое ограничение (C # Reference)

Новое ограничение указывает, что любой аргумент типа в объявлении универсального класса должен иметь открытый конструктор без параметров .Чтобы использовать новое ограничение, тип не может быть абстрактным.


Дополнительные ресурсы

выражения значений по умолчанию (руководство по программированию в C #)

Выражение значения по умолчанию default(T) создает значение default типа T.В следующей таблице показано, какие значения создаются для различных типов:

  • Любой тип ссылки: null
  • Тип числового значения: 0
  • bool: false
  • char: \0
  • enum: значение, полученное с помощью выражения (E)0, где E - это enum идентификатор.
  • struct: значение, полученное путем установки для всех полей типа значения их значения по умолчанию и всех опорных типов для полей null.
  • Тип Nullable: экземпляр, для которого свойство HasValue равно false, а свойство Value не определено.
0 голосов
/ 20 марта 2019

Спасибо за ответы.Я закончил тем, что создал эту функцию, которая, кажется, работает, и я думаю, что это лучший подход:

    private static T ParseResult<T>(string queryResult) where T : new()
    {
        try
        {
            Result<T> res = JsonConvert.DeserializeObject<Result<T>>(queryResult);

            if (res.Success == 1)
            {
                return res.Data;
            }
            return new T();
        }
        catch (Exception) {
            return new T();
        }
    }

и

internal class Result<T>
{
    [JsonProperty("success")]
    public int Success { get; set; }
    [JsonProperty("data")]
    public T Data { get; set; }
}
0 голосов
/ 20 марта 2019

T может быть классом, у которого нет конструктора по умолчанию: в этом случае новый T() будет недопустимым оператором.

Если вы хотите вернуться с объектом по умолчанию, вы можете использовать Activator.CreateInstance вместо возврата default(T), как показано ниже:

return Activator.CreateInstance(typeof(T));

, если вы хотите передать в него параметры, тогда используйте, как показано ниже:

return (T)Activator.CreateInstance(typeof(T), args);
...