#c# #.net #reflection
#c# #.net #отражение
Вопрос:
Я использую следующий код для вывода значений свойств:
string output = String.Empty;
string stringy = "stringy";
int inty = 4;
Foo spong = new Foo() {Name = "spong", NumberOfHams = 8};
foreach (PropertyInfo propertyInfo in stringy.GetType().GetProperties())
{
if (propertyInfo.CanRead) output = propertyInfo.GetValue(stringy, null);
}
Если я запускаю этот код для int
или для Foo
сложного типа, он работает нормально. Но если я запускаю его для string
(как показано), я получаю следующую ошибку в строке внутри foreach
цикла:
System.Reflection.TargetParameterCountException: Parameter count mismatch.
Кто-нибудь знает, что это значит и как этого избежать?
На случай, если кто-нибудь спросит: «почему вы перечисляете через свойства строки», в конечном итоге я надеюсь создать универсальный класс, который будет выводить свойства любого переданного ему типа (который может быть строкой …).
Комментарии:
1. Возможно, было бы более полезно спросить, как создать перечислитель значений свойств на основе отражения?
Ответ №1:
В этом случае одним из свойств строки является индексатор для возврата символа в указанное местоположение. Таким образом, при попытке GetValue
метод ожидает индекс, но не получает его, вызывая исключение.
Чтобы проверить, какие свойства требуют индексации, вы можете вызвать GetIndexParameters
для PropertyInfo
объекта. Он возвращает массив ParameterInfo
, но вы можете просто проверить длину этого массива (если параметров нет, она будет равна нулю)
Комментарии:
1. Спасибо. Как я могу обнаружить свойства на основе индекса и избежать их?
2. Вызовите GetIndexParameters для объекта PropertyInfo. Он возвращает массив ParameterInfo, но вы можете просто проверить длину этого массива (если параметров нет, она будет равна нулю)
Ответ №2:
System.String
имеет индексированное свойство, которое возвращает char
в указанном расположении. Индексируемому свойству требуется аргумент (в данном случае индекс), поэтому возникает исключение.
Ответ №3:
Просто как ссылка… если вы хотите избежать исключения TargetParameterCountException при чтении значений свойств:
// Ask each childs to notify also, if any could (if possible)
foreach (PropertyInfo prop in options.GetType().GetProperties())
{
if (prop.CanRead) // Does the property has a "Get" accessor
{
if (prop.GetIndexParameters().Length == 0) // Ensure that the property does not requires any parameter
{
var notify = prop.GetValue(options) as INotifyPropertyChanged;
if (notify != null)
{
notify.PropertyChanged = options.OptionsBasePropertyChanged;
}
}
else
{
// Will get TargetParameterCountException if query:
// var notify = prop.GetValue(options) as INotifyPropertyChanged;
}
}
}
Надеюсь, это поможет 😉