Неспособный бросить объект типа 'Система. Объект []' к 'MyObject []', что дает?

Функция insert здесь работает, потому что current_node.next = _node является постоянной модификацией объекта в списке, на который указывает head. После этого вызова, даже если current_node собирать мусор (это просто временный указатель), у узла, на который он указывал в строке current_node.next = _node, свойство .next постоянно изменено.

Вот схема добавления нового узла 3 в список 1->2->nil:

(before the `until` loop)

+---------+   +---------+
| data: 1 |   | data: 2 |   
| next: ----> | next: ----> [nil]
+---------+   +---------+
  ^    ^
  |    |
head  current_node 
(after the `until` loop; `current_node.next == nil`)
(and before `current_node.next = _node`)

+---------+   +---------+
| data: 1 |   | data: 2 |   
| next: ----> | next: ----> [nil]
+---------+   +---------+
     ^             ^
     |             |
   head        current_node 
(after `current_node.next = _node`)

+---------+   +---------+   +---------+
| data: 1 |   | data: 2 |   | data: 3 |   
| next: ----> | next: ----> | next: ----> [nil]
+---------+   +---------+   +---------+
     ^             ^
     |             |
   head        current_node 

Кстати, этот метод insert демонстрирует плохой дизайн; каждая вставка представляет собой O (n) линейную операцию времени, требующую обхода всего списка. Улучшенный дизайн класса LinkedList будет предлагать указатель tail, позволяющий O (1) вставлять постоянное время в конец списка. С другой стороны, класс может предложить add_front() без хвостового указателя, который установит new_head.next = old_head и head = new_head.

11
задан Rob Stevenson-Leggett 17 October 2008 в 14:40
поделиться

6 ответов

Альтернативный ответ: дженерики.

public static T[] CreateProperties<T>(IProperty[] properties)
    where T : class, new()
{
    //Empty so return null
    if (properties==null || properties.Length == 0)
        return null;

    //Check the type is allowed
    CheckPropertyTypes("CreateProperties(Type,IProperty[])",typeof(T));

    //Convert the array of intermediary IProperty objects into
    // the passed service type e.g. Service1.Property
    T[] result = new T[properties.Length];
    for (int i = 0; i < properties.Length; i++)
    {
        T[i] = new T();
        ServiceUtils.CopyProperties(properties[i], t[i]);
    }
    return result;
}

Затем Ваш код вызова становится:

Property[] props = ObjectFactory.CreateProperties<Property>(properties);
_service.SetProperties(folderItem.Path, props);

Намного более чистый :)

9
ответ дан 3 December 2019 в 03:05
поделиться

Как другие сказали, массив должен иметь правильный тип для запуска с. Другие ответы показали, как преобразовать подлинный объект [] после факта, но можно создать правильный вид массива для запуска с использования Массива. CreateInstance:

object[] result = (object[]) Array.CreateInstance(type, properties.Length);

Принятие type ссылочный тип, это должно работать - массив будет иметь корректный тип, но Вы будете использовать его в качестве object[] только заполнить его.

5
ответ дан 3 December 2019 в 03:05
поделиться

Это корректно, но это не означает, что можно бросить контейнеры текстового объекта к контейнерам других типов. Объект [] не является тем же самым как Объектом (хотя Вы, странно, могли бросить Объект [] для Возражения).

1
ответ дан 3 December 2019 в 03:05
поделиться

В основном, нет. Существуют некоторые, ограниченные, использование ковариантности массива, но лучше просто знать, какой тип массива Вы хотите. Существует универсальный Массив. ConvertAll, который достаточно легок (по крайней мере, это легче с C# 3.0):

Property[] props = Array.ConvertAll(source, prop => (Property)prop);

Версия C# 2.0 (идентичный в значении) намного менее благоприятна для глазного яблока:

 Property[] props = Array.ConvertAll<object,Property>(
     source, delegate(object prop) { return (Property)prop; });

Или просто создайте новое Свойство [] правильного размера и скопируйте вручную (или через Array.Copy).

Как пример вещей можно сделать с ковариантностью массива:

Property[] props = new Property[2];
props[0] = new Property();
props[1] = new Property();

object[] asObj = (object[])props;

Здесь, "asObj" все еще a Property[] - это это просто доступный как object[]. В C# 2.0 и выше, дженерики обычно делают более оптимальный вариант, чем ковариантность массива.

9
ответ дан 3 December 2019 в 03:05
поделиться

Вы не можете преобразовать массив как этот - он возвращает массив объектов, который отличается от объекта. Попробуйте Массив. ConvertAll

4
ответ дан 3 December 2019 в 03:05
поделиться

в C# 2.0 вы можете сделать это, используя отражение, без использования generics и без знания нужного типа во время компиляции.

//get the data from the object factory
object[] newDataArray = AppObjectFactory.BuildInstances(Type.GetType("OutputData"));
if (newDataArray != null)
{
    SomeComplexObject result = new SomeComplexObject();
    //find the source
    Type resultTypeRef = result.GetType();
    //get a reference to the property
    PropertyInfo pi = resultTypeRef.GetProperty("TargetPropertyName");
    if (pi != null)
    {
        //create an array of the correct type with the correct number of items
        pi.SetValue(result, Array.CreateInstance(Type.GetType("OutputData"), newDataArray.Length), null);
        //copy the data and leverage Array.Copy's built in type casting
        Array.Copy(newDataArray, pi.GetValue(result, null) as Array, newDataArray.Length);
    }
}

Вы захотите заменить все вызовы Type.GetType("OutputData") и GetProperty("PropertyName") на код, который считывается из файла конфигурации.

Я бы также использовал дженерик, чтобы продиктовать создание SomeComplexObject

T result = new T();
Type resultTypeRef = result.GetType();

Но я сказал, что вам не нужно использовать дженерики.

Никаких гарантий по производительности/эффективности, но это работает.

1
ответ дан 3 December 2019 в 03:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: