C# 为每个循环调用所有属性

C# calling all properties, for each loop

我有一个 foreach 循环,我想在 foreach 循环中调用某个 class 的所有属性,这样我就不必全部写出来。

我创造的class

public Person()
    {
        firstname = "";
        surname = "";
        haircolor = "";
        eyecolor = "";
        weight = 0;
        height = 0;
        age = 0;
    }

这是我要压缩的代码

  Console.WriteLine("Please enter the next persons firstname");//new person user input (firstname)
  addperson.firstname = Console.ReadLine();

  Console.WriteLine("Enter the persons surname");//surname
  addperson.surname = Console.ReadLine();

  Console.WriteLine("Enter " + addperson.name + "'s hair color");//hair color
  addperson.haircolor = Console.ReadLine();

  Console.WriteLine("Enter the age of " + addperson.firstname);//age
  addperson.age = Convert.ToInt32(Console.ReadLine());

  Console.WriteLine("Enter the weight of " + addperson.firstname);//weight
  addperson.weight = Convert.ToDouble(Console.ReadLine());

  Console.WriteLine("Enter the height of " + addperson.firstname);//height
  addperson.height = Convert.ToDouble(Console.ReadLine());

我已经开始使用 foreach 循环,我想要一种将所有代码压缩到一个循环中的方法

  foreach (Person.)
            {
                Console.WriteLine("Please enter " +addperson.ToString);
                  Person.addperson = Console.ReadLine();
            }

任何帮助将不胜感激

你需要使用反射才能动态循环每个 属性,我个人不会将其更改为使用反射,因为反射会降低性能,但这里是供你参考的代码:

将 Class 字段更改为属性:

    public class Person
    {
      public string firstname {get;set;}
      public string surname {get;set;}
      public string haircolor {get;set;}
      public string eyecolor {get;set;}
      public string weight {get;set;}
      public string height {get;set;}
      public string age {get;set;}
     }

在您的主要方法中编写此代码:

       Person addperson = new Person();
       PropertyInfo[] props = addperson.GetType().GetProperties();

        foreach(PropertyInfo prop in props)
        {
              Console.WriteLine("Please enter " + prop.Name.ToString());
              string input = Console.ReadLine();
              prop.SetValue(addperson, input, null);
        }

编辑:

这行代码:

 PropertyInfo[] props = addperson.GetType().GetProperties();

Returns Person 类型 (class) 的所有 public 属性,然后每个 PropertyInfo 对象发现 属性 的属性并提供对其元数据的访问.

我会这样做:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace YourNameSpace
{
    class Program
    {
        static void Main(string[] args)
        {
            Person p = GetPersonFromUserInput();
        }

        private static Person GetPersonFromUserInput()
        {
            Person p = new Person();
            Type t = typeof(Person);
            foreach (PropertyInfo pi in t.GetProperties().Where(pi => pi.GetCustomAttribute<PromptAttribute>() != null))
            {
                PromptAttribute attribute = pi.GetCustomAttribute<PromptAttribute>();

                Console.Write("{0}: ", pi.GetCustomAttribute<PromptAttribute>().Prompt);

                if (pi.PropertyType == typeof(int))
                {
                    PromptInteger(p, pi);
                }
                else if (pi.PropertyType == typeof(string))
                {
                    PromptString(p, pi);

                } //add more types in this manner                           
            }

            return p;
        }

        private static void PromptString(Person p, PropertyInfo pi)
        {
            string userInput = Console.ReadLine();
            pi.SetMethod.Invoke(p, new object[] { userInput });
        }

        private static void PromptInteger(Person p, PropertyInfo pi)
        {
            int userInput;
            while (!int.TryParse(Console.ReadLine(), out userInput))
            {
                Console.Write("You have to enter an integer: ");
            }

            pi.SetMethod.Invoke(p, new object[] { userInput });
        }


    }

    public class Person
    {
        [Prompt("Please enter the persons firstname")]
        public string FirstName { get; set; }

        [Prompt("Please enter the persons surname")]
        public string SurName { get; set; }

        [Prompt("Please enter the persons haircolor")]
        public string HairColor { get; set; }

        [Prompt("Please enter the persons eyecolor")]
        public string EyeColor { get; set; }

        [Prompt("Please enter the persons weight")]
        public int Weight { get; set; }

        [Prompt("Please enter the persons height")]
        public int Height { get; set; }

        [Prompt("Please enter the persons age")]
        public int Age { get; set; }
    }

    public class PromptAttribute : Attribute
    {
        public string Prompt { get; private set; }

        public PromptAttribute(string prompt)
        {
            Prompt = prompt;
        }
    }
}

使用自定义属性您可以定义提示。如果您有更多类型,只需在循环中添加更多 else ifs。

一个简单的控制台应用程序,使用反射、linq 和字典:

使用语句:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

你的Class:

public class Person
{
  public string  firstname {get; set;}
  public string surname { get; set; }
  public string haircolor { get; set; }
  public string eyecolor { get; set; }
  public string weight { get; set; }
  public string height { get; set; }
  public string age { get; set; }
}

控制台应用程序:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            var per = new Person();
            var perDict = new Dictionary<string, string>();


            foreach (
                var c in 
                    per.GetType()
                        .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                            .ToDictionary(prop => prop.Name, prop => prop.GetValue(per,null))
                        )
            {

            Console.Write("Greetings, Please Enter Your Value for: " + c.Key + " ");
            var answer = Console.ReadLine();
            perDict.Add(c.Key, answer);
            per.GetType().GetProperty(c.Key).SetValue(per,answer, null);
            }
        }
    }

}