То, как я создаю и получаю доступ к новому экземпляру Анонимного класса, передало в качестве параметра в C#?

erow = ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row

В вашем коде было 2 ошибки. Во-первых, команда xlUp, а не x1Up - «xl» означает «Excel», а не «X One» - это прекрасный пример того, почему вы почти всегда должны использовать Option Explicit [119 ]

Второе: ваш код как есть попытается поместить .Value из ячейки в нетипизированную переменную erow - поскольку ячейка пуста (так как ячейка ниже последней ячейка с данными), это означает, что erow будет всегда будет 0. И строка 0 не существует для помещения данных.

Вместо этого, используя Range.Row, мы получаем следующий номер строки для вставки данных в

10
задан Mark Brittingham 26 January 2009 в 00:20
поделиться

2 ответа

Анонимные типы инкапсулируют ряд свойств только для чтения. Это объясняет

  1. Почему Type.GetFields возвращает пустой массив при вызове на анонимном типе: анонимные типы не имеют общедоступных полей.

  2. Общественные собственности на анонимном типе только для чтения и не могут иметь своего набора значений вызовом к PropertyInfo.SetValue. Если Вы звоните PropertyInfo.GetSetMethod на свойстве в анонимном типе Вы получите назад null.

На самом деле, если Вы изменяетесь

var properties = TypeDescriptor.GetProperties(sample);
while (nwReader.Read()) {
    // No way to create a constructor so this call creates the object without calling a ctor. Could this be a source of the problem?
    T obj = (T)FormatterServices.GetUninitializedObject(typeof(T)); 
    foreach (PropertyDescriptor info in properties) {
        for (int i = 0; i < nwReader.FieldCount; i++) {
            if (info.Name == nwReader.GetName(i)) {
                // This loop runs fine but there is no change to obj!!
                info.SetValue(obj, nwReader[i]);
                break;
            }
        }
    }
    fdList.Add(obj);
}

кому:

PropertyInfo[] properties = sample.GetType().GetProperties();
while (nwReader.Read()) {
    // No way to create a constructor so this call creates the object without calling a ctor. Could this be a source of the problem?
    T obj = (T)FormatterServices.GetUninitializedObject(typeof(T));
    foreach (PropertyInfo info in properties) {
        for (int i = 0; i < nwReader.FieldCount; i++) {
            if (info.Name == nwReader.GetName(i)) {
                // This loop will throw an exception as PropertyInfo.GetSetMethod fails
                info.SetValue(obj, nwReader[i], null);
                break;
            }
        }
    }
    fdList.Add(obj);
}

Вы получите исключение, сообщающее Вам, что метод набора свойств не может быть найден.

Теперь, для решения проблемы, что можно сделать, использовать Activator.CreateInstance. Я сожалею, что я слишком ленив для вывода кода для Вас, но следующее продемонстрирует, как использовать его.

var car = new { Make = "Honda", Model = "Civic", Year = 2008 };
var anothercar = Activator.CreateInstance(car.GetType(), new object[] { "Ford", "Focus", 2005 });

Так просто пробегите цикл, как Вы сделали, для заполнения объектного массива, которому необходимо передать Activator.CreateInstance и затем звоните Activator.CreateInstance когда цикл сделан. Порядок свойства важен здесь, поскольку два анонимных типа являются тем же, если и только если у них есть то же количество свойств с тем же типом и тем же именем в том же порядке.

Для больше, посмотрите страницу MSDN на анонимных типах.

Наконец, и это действительно в стороне и не релевантно Вашему вопросу, но следующему коду

foreach (PropertyDescriptor info in properties) {
    for (int i = 0; i < nwReader.FieldCount; i++) {
        if (info.Name == nwReader.GetName(i)) {
            // This loop runs fine but there is no change to obj!!
            info.SetValue(obj, nwReader[i]);
            break;
        }
    }
}

мог быть упрощен

foreach (PropertyDescriptor info in properties) {
            info.SetValue(obj, nwReader[info.Name]);
}
25
ответ дан 3 December 2019 в 15:22
поделиться

Вопрос № 2:

Я действительно не знаю, но я был бы склонен использовать Активатор. CreateObject () вместо FormatterServices. GetUninitializedObject (), потому что Ваш объект не мог бы быть создан правильно. GetUninitializedObject () не будет работать, конструктор по умолчанию как CreateObject () будет, и Вы не обязательно знаете то, что находится в черном квадрате T...

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

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