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

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

Чтобы быть более точным, все открытые свойства с типом строки в этом определяемом пользователем классе должны быть "очищены" в конце выполнения.

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

Поэтому я решил написать вспомогательный метод (как метод расширения) на C#, который перебирает свойства экземпляра объекта и динамически обращается к ним / манипулирует ими. Я видел несколько похожих вопросов об итерации свойств здесь, но пока не видел ничего об изменении значений свойств. Вот что я попробовал:

public static void SetDefaultStringValues(this Object myObject)
{
    PropertyInfo[] aryProperties = entityObject.GetType().GetProperties();

    foreach (object property in aryProperties)
    {
        if (property is String) 
        {
            //property = String.Empty;
        }
    }
}

Комментируемая часть должна была быть строкой, в которой я устанавливал переменные, но это не было историей успеха:) Я буду признателен за любую помощь.

4 ответа

Решение

Ты можешь использовать PropertyDescriptor из System.ComponentModel для ленивого кодирования. Предполагая, что вы хотите перебрать общедоступные методы экземпляров (не статические), вы можете попробовать следующий пример:

Тестовый класс:

public class TestClass
{
    private int mIntMemeber = 0;                    // # to test int type   
    private string mStringMember = "abc";           // # to test string type (initialized)
    private string mNullStringMember = null;        // # to test string type (null)

    private static string mStaticNullStringMember;  // # to test string type (static)

    // # Defining properties for each member
    public int IntMember                            
    {
        get { return mIntMemeber; }
        set { mIntMemeber = value; }                
    }

    public string StringMember                      
    {
        get { return mStringMember; }
        set { mStringMember = value; }
    }

    public string NullStringMember
    {
        get { return mNullStringMember; }
        set { mNullStringMember = value; }
    }

    public static string StaticNullStringMember
    {
        get { return mStaticNullStringMember; }
        set { mStaticNullStringMember = value; }
    }
}

SetDefaultStringValues ​​() Метод расширения:

public static string SetDefaultStringValues(this TestClass testClass)   
{
    StringBuilder returnLogBuilder = new StringBuilder();
    // # Get all properties of testClass instance
    PropertyDescriptorCollection propDescCollection = TypeDescriptor.GetProperties(testClass);
    // # Iterate over the property collection
    foreach (PropertyDescriptor property in propDescCollection)
    {
        string name = property.Name;
        Type t = property.PropertyType; // # Get property type
        object value = property.GetValue(testClass); // # Get value of the property (value that member variable holds)

        if (t == typeof(string)) // # If type of propery is string and value is null
        {
            property.SetValue(testClass, String.Empty); // # Set value of the property (set member variable)
            value = String.Empty; // # <-- To prevent NullReferenceException when printing out
        }

        returnLogBuilder.AppendLine("*****\nName:\t{0}\nType:\t{1}\nValue:\t{2}", name, t.ToString(), value.ToString());
    }

    returnLogBuilder.AppendLine("*****");
    return returnLogBuilder.toString();
}

Вы также можете проверить, если значение равно нулю в цикле. SetDefaultStringValues Параметр метода может быть любым экземпляром объекта. Вы можете изменить его на SetDefaultStringValues(this object o) и использовать его как метод расширения для вашего определенного экземпляра класса.

Используйте метод PropertyInfo.SetValue, подробнее об этом здесь

    foreach (PropertyInfo property in aryProperties)
    {
        if (property.PropertyType == typeof(string) && property.CanWrite) 
        {
            property.SetValue(myObject, "", null);
        }
    }

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

if (property.PropertyType == typeof(string) && property.GetSetMethod() != null)
    property.SetValue(entityObject, "");
Другие вопросы по тегам