Очисти мой код с отражением - PullRequest
2 голосов
/ 17 июня 2011

Я хочу перебрать свой класс Car с отражением, чтобы удалить все нулевые значения и заменить их более подходящими значениями, такими как string = "".

    [Serializable()]
public class Car
{
    public string model;
    public int year;
    public List<Owner> owner;
}

[Serializable()]
public class Owner
{
    public string firstName;
    public string lastName;
}

Я сделал это до сих пор

   public void LoopEverythingAndFix(object type)
    {
        var prop = type.GetType().GetFields();

        foreach (var fieldInfo in prop)
        {
            if (GetType(fieldInfo))
            {
                var value = fieldInfo.GetValue(type);

                if (value == null)
                    fieldInfo.SetValue(type, GetDefaultValue(fieldInfo));
            }
            else
            {
                LoopEverythingAndFix(fieldInfo);
            }
        }
    }
    public bool GetType(System.Reflection.FieldInfo fieldInfo)
    {
        if (fieldInfo.FieldType == typeof(string))
            return true;

        if (fieldInfo.FieldType == typeof(bool))
            return true;

        if (fieldInfo.FieldType == typeof(int))
            return true;

        if (fieldInfo.FieldType == typeof(decimal))
            return true;

        return false;
    }

Метод GetType должен знать, является ли текущее поле классом, подобным классу "owner", или его значением или ссылочным полем, например, int / string, и если это тип "owner", то я хочуЗациклите это и исправьте эти свойства.

Проблема в том, что он находит «владельца» в классе автомобиля и выполняет команду:

 LoopEverythingAndFix(fieldInfo);

, где проблема, потому чтоя посылаю fieldInfo методу LoopEverythingAndFix и когда он возвращается в цикл, он получает 0 полей в type.GetType().GetFields().Это список, и я хочу зациклить элементы списка и отправить их в метод LoopEverythingAndFix

Ответы [ 3 ]

3 голосов
/ 17 июня 2011

Вы пытаетесь вызвать LoopEverythingAndFix для типа отражения FieldInfo, а не для реального объекта, который вы хотите исправить.

Чтобы исправить, замените это:

LoopEverythingAndFix(fieldInfo);

С этим:

LoopEverythingAndFix(fieldInfo.GetValue(type));
0 голосов
/ 17 июня 2011

Есть несколько проблем с вашим кодом, которые необходимо устранить:

  1. Вы выполняете нулевую проверку для известных типов значений. Экземпляр ValueType, отличный от Nullable<T>, никогда не будет нулевым. Это действие не является необходимым и ухудшает производительность. Я исправил это ниже.

  2. Вы не учитываете обстоятельство пустого поля ссылочного типа, кроме string. Например, что должно произойти, если есть ноль Owner или нуль List<Owner>?

  3. Поскольку вы не опубликовали функцию GetDefaultValue(), ее подпись немного неясна. Я предполагаю, что он принимает FieldInfo и разрешает ненулевое значение по умолчанию на основе типа поля. Поскольку в действительности это применимо только к аргументу string, было бы лучше заменить вызов на string.Empty. Я указал на это в комментарии ниже.

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

public void LoopEverythingAndFix(object instance)
{
    var fields = instance.GetType().GetFields(BindingFlags.Public|BindingFlags.Instance)
    foreach(var fieldInfo in fields){
       var fieldType = fieldInfo.FieldType;
       if(!fieldType.IsValueType){
          bool isString = fieldType == typeof(string);
          var fieldValue = fieldInfo.GetValue(instance);
          if(fieldValue != null){
                if(!isString){
                    // This should recursion be called when the type is a 
                    // complex (non-string) reference type that is not null
                    LoopEverythingAndFix(fieldValue);
                }
                // You don't need to fix a non-null string value
          }
          else{
              if(isString){
                  // since you didn't post the code for this, I am assuming 
                  // it works correctly, but it may be that you can just replace
                  // GetDefaultValue(fieldInfo) with string.Empty 
                  fieldInfo.SetValue(instance, GetDefaultValue(fieldInfo));
              }
              else{
                  // It is unclear how you want to handle a complex reference type 
                  // field with a null value.  That code should go here.
              }
          }
       } 
    }
}
0 голосов
/ 17 июня 2011

Кажется, проблема в том, что вместо передачи объекта Owner вы передаете ссылку на статический класс Owner. Таким образом, у вас уже есть тип владельца.

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