jeudi 18 juin 2020

Create an object using Expression Trees without generic arguments

I have a class that is a bit like the following

public class SpecialList<T> : List<T>
{
    public SingleOrList() { }
    public SingleOrList(IEnumerable<T> list) : base(list) {}
    ...
}

When converting it from JSON, it can be turned into this special list as either a single object, or an array of that object in the following manner.

...

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    var token = JToken.Load(reader);

    if (token.Type == JTokenType.Array)
    {
        var originalList = token.ToObject(objectType.BaseType, serializer);
        return Activator.CreateInstance(objectType, originalList);
    }

    var list = (IList) Activator.CreateInstance(objectType);
    var genericType = objectType.GetGenericArguments().Single();
    var single = token.ToObject(genericType, serializer);

    list.Add(single);

    return list;
}

Ignoring the fact of whether or not this is a good idea for the moment, I was interested in whether you could use / how you would use complied expression trees here instead of Activator.CreateInstance to create the classes.

Most of the examples I've seen use generics which is not possible for me here as I don't know up front the generic type, e.g.

public static Func<T> Instance = Expression.Lambda<Func<T>>(Expression.New(typeof(T))).Compile();




Aucun commentaire:

Enregistrer un commentaire