Как привести объект к списку <object>и превратить его в массив? - PullRequest
0 голосов
/ 07 февраля 2019

Я пытаюсь привести список к типу, но у меня возникают проблемы в следующей строке:

value = isArray ? ((List<object>)value).ToArray() : value;

Я получаю сообщение об ошибке, говорящее о том, что невозможно преобразовать из типа источника втип назначения .Однако, если я изменю List<object> на List<int>, это сработает.Я не могу этого сделать из-за того, что список, скорее всего, не будет int каждый раз, поскольку он динамический.

Есть ли Invoke или что-то, что я могу сделать, чтобы передать типв качестве параметра, чтобы сказать, что invoke вернет List<x> (где x - это какой-то динамический тип)?

var castMethod = this.GetType().GetMethod("CastList").MakeGenericMethod(type);
value = castMethod.Invoke(null, new object[] { value });
value = isArray ? ((List<object>)value).ToArray() : value;

public static List<T> CastList<T>(List<object> o) {
    var list = new List<T>();
    foreach (var i in o) { list.Add((T)i); }
    return list;
}

В конце значение value будет либо List, либоМассив.

Редактировать

Вот полный метод:

void SaveDataLocal() {
    keyValues.ForEach(item => {
        var field = GameData.save.GetType().GetField(item.key);
        var value = GetValue(item);
        var isArray = field.FieldType.IsArray;
        var isList = IsList(value);

        // Convert arrays to proper types
        if (isArray || isList) {
            Type type;
            // Get the array type
            if (isArray) type = field.FieldType.GetElementType();
            // Get the list type
            else type = field.FieldType.GetGenericArguments().Single();
            // Do the cast
            var castMethod = this.GetType().GetMethod("CastList").MakeGenericMethod(type);
            value = castMethod.Invoke(null, new object[] { value });
            value = isArray ? ((List<object>)value).ToArray() : value;
        }

        field.SetValue(GameData.save, value);
    });
    GameData.Save();
}

Вот мой объект ключ / значение:

class KeyValue {
    public string key;
    public object value;

    public KeyValue(string key, object value) {
        this.key = key;
        this.value = value;
    }
}

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Списки уже подготовлены для работы с массивами.Если у вас есть:

List<object> MyList;

Тогда вы можете использовать его как массив.Например:

object obj = MyList[2];
0 голосов
/ 07 февраля 2019

Как обсуждалось в комментариях, на самом деле вам нужно взять List<object> (каждый из которых object на самом деле T и может иметь тип значения в штучной упаковке) и превратить его вList<T> или T[], в зависимости от флага bool.

Самое простое, что нужно сделать, это слегка изменить метод CastList:

var castMethod = this.GetType().GetMethod("CastList").MakeGenericMethod(type);
value = castMethod.Invoke(null, new object[] { value, isArray });

public static object CastList<T>(List<object> o, bool isArray) {
    var result = o.Cast<T>();
    return isArray ? (object)result.ToArray() : result.ToList();
}
0 голосов
/ 07 февраля 2019

Кажется, вам на самом деле не нужно List<>.Вам нужен только IEnumerable<>.

(IEnumerable<object>)value).ToArray()

Почему это работает, а List<> - нет?Потому что IEnumerable<int> - это IEnumerable<object>.Но List<int> - это , а не a List<object>, если бы это было так, вы могли бы .Add(new Object()) сказать List<int>.

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