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

获取未知大小结构(c)中的所有变量

  •  0
  • Scott  · 技术社区  · 17 年前

    我有一个项目,在这个项目中,我必须从一个不同类的结构中获取所有变量,并将它们的所有名称添加到一个表单的组合框中。我目前的主要问题是以一种可以将每个变量单独添加到组合框中的方式遍历结构。我试过这样做:

            msgVars vars = new msgVars();
            foreach (object obj in vars)
            {
                comboBox1.Items.Add(GetName(obj));
            }
    

    但正如您可能知道的,您不能以这种方式遍历结构。我有没有办法不把变量硬编码?

    另外,作为参考,这是getname函数:

    static string GetName<T>(T item) where T : struct
    {
        var properties = typeof(T).GetProperties();
        if (properties.Length == 1)
        {
            return properties[0].Name;
        }
        else
        {
            return null;
        }
    }
    
    3 回复  |  直到 17 年前
        1
  •  0
  •   LBushkin    17 年前

    如果您正在寻找一种在运行时访问结构(或类)属性的方法,而不预先定义属性集的代码,那么您可能需要使用反射。

    下面是一个例子:

    struct MyStruct
    {
        private readonly int m_Age;
        private readonly string m_LastName;
        private readonly string m_FirstName;
    
        public int Age { get { return m_Age; } }
        public string LastName { get { return m_LastName; } }
        public string FirstName { get { return m_FirstName; } }
    
        public MyStruct( int age, string last, string first )
        {
            m_Age = age;
            m_LastName = last;
            m_FirstName = first;
        }
    }
    
    class StructReflection
    {
        public static void Main(string[] args)
        {
            var theStruct = new MyStruct( 40, "Smith", "John" );
            PrintStructProperties( theStruct );
        }
    
        public static void PrintStructProperties( MyStruct s )
        {
            // NOTE: This code will not handle indexer properties...
            var publicProperties = s.GetType().GetProperties();
            foreach (var prop in publicProperties)
                Console.WriteLine( "{0} = {1}", prop.Name, prop.GetValue( s, null ) );
        }
    }
    
        2
  •  0
  •   James    17 年前

    你可以尝试使用反射。把信息存储在哈希表中怎么样?

    public Hashtable GetPropertyInfo(Person person)
    {
        var properties = new Hashtable();
        PropertyInfo[] propInfo = person.GetType().GetProperties();
        foreach (PropertyInfo prop in propInfo)
        {
             properties.Add(prop.Name, prop.GetValue(person, null));
        }
    
        return properties;
    }
    

    然后您可以通过以下方式写出信息:

    var person = new Person()
    Person.Name = "Test";
    Person.Age = 21;
    
    var PropertyInfo = GetPropertyInfo(person);
    foreach (string key in PropertyInfo.Keys)
    {
         Console.WriteLine("{0} = {1}", key, PropertyInfo[key]);    
    }
    
        3
  •  0
  •   Panagiotis Kanavos    16 年前

    结构是单个实体,而不是变量集合。这意味着您不能“迭代”它的属性。您需要做的是获取一个属性名集合并对其进行迭代。getname函数无法执行此操作,因为它只返回第一个属性的名称。

    要将属性名添加到组合框中,只需执行以下操作:

     var vars = new msgVars();
     foreach(var name in GetNames(vars))
         comboBox1.Items.Add(name);
    

    实际上,获取属性名非常简单,您可以完全去掉getnames,只需编写

      foreach (var prop in typeof(msgVars).GetProperties())
          comboBox1.Items.Add(prop.Name);
    

    有多种方法可以编写getnames来返回名称集合。可以用属性名填充列表,但最简单的方法是让它返回如下迭代器:

     public static IEnumerable<string> GetNames<T>(T obj) where T:struct
     {
         var properties = typeof (T).GetProperties();
         foreach (var propertyInfo in properties)
         {
             yield return propertyInfo.Name;
         }
     }
    

    最后,您不需要将结构的实例传递给方法,因为您正在枚举结构属性名称,而不是它们的值。你可以这样重写getnames

     public static IEnumerable<string> GetNames<T>() where T:struct
     {
         var properties = typeof (T).GetProperties();
         foreach (var propertyInfo in properties)
         {
            yield return propertyInfo.Name;
         }
      }
    

    像这样加载名字

      foreach(var name in GetNames<msgVars>())
          comboBox1.Items.Add(name);
    
    推荐文章