如何在运行时操作用户定义的类的属性?

时间:2013-02-07 11:33:31

标签: c# reflection properties helpermethods

我有一个巨大的用户定义的类,它有很多属性,其中一些必须设置一定值。

更具体地说,此用户定义的类中字符串的所有公共属性必须为执行结束时“清空”

所以我逐个到达所有公共场所(如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 个答案:

答案 0 :(得分:2)

使用PropertyInfo.SetValue方法,在here

中有更多相关内容

答案 1 :(得分:1)

您可以使用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();
}

您还可以检查循环中是否 null SetDefaultStringValues方法参数可以是任何对象实例。您可以将其更改为SetDefaultStringValues(this object o),并将其用作已定义的类实例的扩展方法

答案 2 :(得分:0)

您需要使用不同的语法来检查属性类型;此外,你要检查该物业是否有公共二传手。

if (property.PropertyType == typeof(string) && property.GetSetMethod() != null)
    property.SetValue(entityObject, "");

答案 3 :(得分:0)

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