Как манипулировать свойствами пользовательского класса во время выполнения?
У меня есть огромный пользовательский класс с множеством свойств, и некоторые из них должны быть установлены с определенным значением.
Чтобы быть более точным, все открытые свойства с типом строки в этом определяемом пользователем классе должны быть "очищены" в конце выполнения.
Таким образом, я достиг всех общедоступных свойств по одному (например, 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, "");