代码之家  ›  专栏  ›  技术社区  ›  etoisarobot

如何循环访问类的所有属性?

c#
  •  2
  • etoisarobot  · 技术社区  · 14 年前

    有没有一种方法可以从类的构造函数中循环遍历所有属性,这样我就可以设置它们的所有默认值,而不必像这样列出每个属性

    this.prop1 = "?";
    //repeat for each prop
    

    例如:

    public class thisClass()
    {
        library()
        {
            foreach (property as p in thisClass)
            {
               p.value = "?";
            }
        }
    
    public string prop1 {get; set;}
    public string prop2 {get; set;}
    etc.
    } 
    
    5 回复  |  直到 14 年前
        1
  •  6
  •   Reed Copsey    14 年前

    你可以通过反射(通过 Type.GetProperties PropertyInfo.SetValue 但是我不推荐。它将降低可读性和可维护性,并对性能产生负面影响。

    列出属性并定义它们的初始值的好处是,您可以在构造函数中看到它,就在前面。或者,您可以为属性提供支持字段,并在字段上直接定义它们。

        2
  •  1
  •   Stefan Steinegger    14 年前

    我真的不会这么做。属性应该由构造函数显式初始化,这就是它们存在的原因。别忘了初始化字段。

    但我不知道你为什么需要它,所以这里有一些代码。

    要可靠地设置任何属性(包括私有属性)并不容易。通常我这样做(在我脑子里,我明天会用我真正的代码检查):

    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];
        }
    }
    
        3
  •  0
  •   driis    14 年前

    我不推荐,但既然你问:

    var props = GetType().GetProperties().Where(prop => prop.CanWrite && prop.PropertyType == typeof(string))
    foreach(var prop in props) 
        prop.SetValue(this, "?", null);
    
        4
  •  0
  •   Gleno    14 年前

    像这样做。工作很好。唯一的问题是你不能依赖订单。

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

    horses mouth : getProperties方法不返回特定顺序的属性,例如字母顺序或声明顺序。您的代码不能依赖于返回属性的顺序,因为顺序不同。

    也就是说,你的问题更好(比如软件设计 更好的 )通过手动分配所有属性来解决。如果您发现自己的属性太多,那么应该使用容器来代替。一 List<> 例如。

        5
  •  0
  •   Reddog    14 年前

    我可能不建议将所有属性设置为非空的固定值…尤其是,假定所有属性都对该默认状态满意,甚至更天真的是,类的用户最可能期望为空(或者更准确地说是 default(T) )代替未知值。

    作为一个建议,如果这是为了显示“?”在一个还不知道特定值的UI中,也许您可以在框架内使用适当的绑定类。

    例如,WinForms绑定类具有“NullValue”属性,当数据源中包含null或dbnull.Value时,该属性将传递给绑定控件的属性。

    但是,如果你真的想沿着你所要求的道路走下去,就像上面提到的那样, Type.GetProperties() 应该有技巧。确保考虑继承、抽象、重写或虚拟属性的情况,以及设置默认值是否合适,尤其是考虑到当您实际上没有已知值时,将规范设置为/保留为空/默认(T)的事实。