开发者

How to Loop through all the properties of a Class?

开发者 https://www.devze.com 2023-01-19 03:50 出处:网络
Is there a way to loop through all the properties from within a class\'s constructor so I can set all their default values instead of having to list each one like

Is there a way to loop through all the properties from within a class's constructor so I can set all their default values instead of having to list each one like

this.prop1 = "?";
//repeat for e开发者_如何学Goach prop

For example:

public class thisClass()
{
    library()
    {
        foreach (property as p in thisClass)
        {
           p.value = "?";
        }
    }

public string prop1 {get; set;}
public string prop2 {get; set;}
etc.
} 


You could do this with Reflection (via Type.GetProperties and PropertyInfo.SetValue), but I wouldn't recommend it. It will reduce the readability and maintainability, as well as have a negative performance impact.

The advantage of listing out the properties and defining their initial values is that you see it, right up front, in your constructor. You can, alternatively, provide the backing field for your properties, and define them inline on the fields.


I wouldn't do it, really. Properties should be explicitly initialized by constructors, that's why they exist. Don't forget to initialize fields as well.

But I don't know why you need it, so here is some code.

It is not so easy to reliably set any property, including private properties. Usually I do this like this (out of my head, I will check with my real code tomorrow):

var properties = this.GetType().Properties(
  BindingFlags.Instance 
  | BidningFlags.NonPublic 
  | BindingFlags.Public);

foreach(PropertyInfo property in properties)
{
    // if a property is declared on a base type with a private setter,
    // get the definition again from the declaring type,
    // unless you can't call the setter.
    // Probably it is even more reliable to get the properties setter
    // from the declaring type.
    if (property.DeclaringType != this)
    {
      property = property.DeclaringType.GetProperty(
        property.PropertyName,
        BindingFlags.Instance 
        | BidningFlags.NonPublic 
        | BindingFlags.Public);
    }

    if (property.CanWrite)
    {
      // assumed that you define a dictionary having the default values.
      property.SetValue(this, defaultValues[property.PropertyType];
    }
}


I would not recommend it, but since you are asking:

var props = GetType().GetProperties().Where(prop => prop.CanWrite && prop.PropertyType == typeof(string))
foreach(var prop in props) 
    prop.SetValue(this, "?", null);


Do something like this. Works great. Only problem you can't rely on order.

var properties = typeof(T).GetProperties();
foreach(var prop in properties ){

}

From the horses mouth: The GetProperties method does not return properties in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which properties are returned, because that order varies.

That said, your problem is better (as in software design better) addressed by just assigning all properties manually. If you find yourself in a situation with too many properties, you should use a container instead. A List<>, for example.


I probably wouldn't recommend setting all properties to a fixed value other than null... Particularly as it may be naive to assume that all of your properties are happy with that default state and even more so, that users of your class would most likely be expecting null (or more precisely default(T)) in place of an unknown value.

Just as a suggestion, if this is for the sakes of displaying the "?" in a UI when the specific values are not yet known then perhaps you could make use of the appropriate binding classes within the framework.

For example, winforms Binding class has "NullValue" property that will be passed to the bound control's property when the datasource has null or DbNull.Value in it.

But if you really want to go down the path that you've asked for then, as suggested above, the Type.GetProperties() should do the trick. Make sure you consider cases of inherited, abstract, overridden or virtual properties and whether setting the default value is appropriate - particularly in light of the fact that the norm is set/leave a value to null/default(T) when you don't actually have a known value.

0

精彩评论

暂无评论...
验证码 换一张
取 消