How to check if T is a list of objects in a generic method

I am trying to write a general deserialization method from json files using Json.NET
I want to be able to support deserialization of files containing objects as well as arrays of objects. The following are simplified versions of two common methods that I have at the moment:

/// <summary>   Deserializes object or an array of objects from a list of files. </summary>
public static List<T> Deserialize<T>(List<string> filePathsList)
{
    var result = new List<T>();
    foreach (var file in filePathsList)
        // HOW DO I FIND OUT IF T IS A LIST HERE?
        // Resharper says: the given expression is never of the provided type
        if (typeof(T) is List<object>)
        {
            var deserialized = Deserialize<List<T>>(file);
            result.AddRange(deserialized);
        }
        // Resharper says: Suspicious type check: there is not type in the solution
        // which is inherited from both 'System.Type' and 'System.Collections.IList'
        else if (typeof(T) is IList)
        {
            // deserializing json file with an array of objects
            var deserialized = Deserialize<List<T>>(file);
            result.AddRange(deserialized);
        }
        else
        {
            // deserializing a single object json file
            var deserialized = Deserialize<T>(file);
            result.Add(deserialized);
        }
    return result;
}


/// <summary>   Deserializes object or an array of objects from a file. </summary>
public static T Deserialize<T>(string filepath)
{
    return JsonConvert.DeserializeObject<T>(File.ReadAllText(filepath));
}

The problem is that I need to know if T is an object or a list of objects, before deserialization. How to check this inside the general method? Because resharper gives me warnings and I can not understand this.


: , @Medo42, Deserialize() List<List<Something>> , , json , . , T .

.

+4
4

, .

// Resharper says: the given expression is never of the provided type
if (typeof(T) is List<object>)

. is , , , typeof(T) List<object>. typeof(T) Type, T. ( )

if (typeof(T) == typeof(List<object>))

, , T List<object>. List<object>,

if (typeof(List<object>).IsAssignableFrom(typeof(T)))

. , , List<object> . , , List<T> . List<T>.

, . , , , . #, List<Cat> List<Mammal>, , - List<Cat>.

, drf dotctor - , , :

typeof(T).GetGenericTypeDefinition() == typeof(List<>)

, :

var deserialized = Deserialize<List<T>>(file);

, T List<Something>, List<List<Something>>, , , , .

+10

.

if (typeof(T).Name == "List`1")
{
    // T is a generic list
}

drf, , , :

if (typeof(T).GetGenericTypeDefinition() == typeof(List<>))
{
    // T is a generic list
}
+4

You don’t need it, you can simplify your code using LINQ !!!

/// <summary>
///     Deserializes object or an array of objects from a list of files.
/// </summary>
public static List<T> Deserialize<T>(List<string> filePathsList)
{
    return filePathsList
        .Select(System.IO.File.ReadAllText)
        .Select(JsonConvert.DeserializeObject<T>)
        .ToList();
}
+2
source

@Hamid Pourjam's answer is good, but throws an exception for non-generic types, so you should also check IsGenericType. Here is a helper method for this.

public bool IsList(object o)
{
    if (o == null) return false;

    var type = o.GetType();
    return o is IList && type.IsGenericType && type.GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>));
}

Using:

public class Foo
{
    public string Key { get; set; }
}

// #1
var foo = new Foo { Key = "value" };

// #2
var foos = new List<Foo>();
foos.Add(foo);

// #3
var lst = new List<object>();
lst.Add(new { Name = "John" });

IsList(foo); // false
IsList(foos); // true
IsList(lst); // true
0
source

Source: https://habr.com/ru/post/1620902/


All Articles