Хобрук: Ваш путь к мастерству в программировании

В Reflection, как установить правильное значение свойства?

Моя цель — найти все свойства типа «строка» и присвоить их определенному строковому значению, например «Это тестовая строка».

Теперь я могу найти все свойства строкового типа в классе, но всегда возникают проблемы при присвоении строкового значения свойству в классе, которое является свойством класса другого класса.

 public class Credit_Card
{
    public string brand { get; set; }
    public int billing_phone { get; set; }
    public string credit_card_verification_number { get; set; }
    public Expiration expiration { get; set; }
}

public class Expiration
{
    public string month { get; set; }
    public string year { get; set; }
}

 class Program
{
    static void Main(string[] args)
    {
        Credit_Card credcard = new Credit_Card { brand = "Visa", billing_phone = 12345, credit_card_verification_number = "1234", expiration = new Expiration { month = "11", year = "2016" } };
        foreach (PropertyInfo prop in GetStringProperties(credcard.GetType()))
        {
            prop.SetValue(credcard,"testing string!!",null);
            Console.WriteLine(prop.GetValue(credcard,null));
        }
        Console.ReadLine();
    }

    public static IEnumerable<PropertyInfo> GetStringProperties(Type type)
    {
        return GetStringProperties(type, new HashSet<Type>());
    }

    public static IEnumerable<PropertyInfo> GetStringProperties(Type type, HashSet<Type> alreadySeen)
    {
        foreach (var prop in type.GetProperties())
        {
            var propType = prop.PropertyType;
            if (propType == typeof(string))
                yield return prop;
            else if (alreadySeen.Add(propType))
                foreach (var indirectProp in GetStringProperties(propType, alreadySeen))
                    yield return indirectProp;
        }
    }
}

Он всегда выдает исключение, когда цикл переходит к свойству «месяц» класса Expiration.

Как я могу присвоить правильное значение правильному экземпляру?

13.04.2015

  • Какое исключение вы получаете? 14.04.2015
  • Исключение System.Reflection.TargetException не было обработано, и сообщение не соответствует целевому типу. Это произошло в prop.SetValue(credcard,testing string!!,null) 14.04.2015

Ответы:


1

Если вы хотите присвоить значения month и year, вам нужно будет получить их PropInfo, выполнив Type.GetType(CredCard.Expiration).Properties, потому что они не являются свойствами credcard, но являются свойствами credcard.Expiration.

Вам нужно будет проверить свойства и назначить их credcard.Expiration, а не credcard.

// prop.Name == "month" || prop.Name == "year"
prop.SetValue(credcard.Expiration, "somestring");

Другой альтернативой может быть назначение нового объекта Expiration свойству Expiration:

if(prop.Name.Equals("Expiration"))
{
  var expiration = new Expiration
  {
   month = "someString",
   year = "someString"
  };
  prop.SetValue(credcard,expiration);
}
13.04.2015
  • Привет, я хотел бы, чтобы этот метод был как можно более универсальным, и я не хочу содержать какое-либо свойство в формате жесткого кода. Моя цель состоит в том, чтобы этот метод мог применять любые классы с любым свойством типа класса. Спасибо. 14.04.2015

  • 2

    Глядя на код, вы захватываете все строковые свойства Credit_Card, а затем рекурсивно захватываете все строковые свойства дочерних объектов.

    Ваша проблема связана с тем, что он возвращает string month из Expiration. Затем вы пытаетесь установить свойство Expiration.month в своем экземпляре Credit_Card credcard.

    Это не работает. Цель должна соответствовать тому же Type, что и PropertyInfo. Вот почему вы получаете:

    System.Reflection.TargetException не было обработано, а сообщение: «Объект не соответствует целевому типу».

    Вам нужно разделить свой цикл, чтобы вы выполняли их в правильной иерархической цепочке и имели правильный экземпляр (цель), который будет обновлен вашими данными.

    13.04.2015
    Новые материалы

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..

    Обзор 20 основных и современных методов работы с массивами в JavaScript
    Вы знаете их всех? В этом коротком посте я покажу сводку методов, доступных в JavaScript для работы с массивами. Я надеюсь, что вы найдете это полезным! В конце поста вы найдете ссылку на..

    Да, но я чувствую необходимость указать, что это или не единственные два.
    Да, но я чувствую необходимость указать, что это или не единственные два. Обучение с подкреплением (в качестве примера) также является важным.