0

I have a class with multiple properties. Each property have type another class.

public class FirstClass
{
    public Field Field1 { get; set; }
    public Field Field2 { get; set; }
    public Field Field3 { get; set; }
    public Field Field4 { get; set; }
    public Field Field5 { get; set; }
}

Field class will look like this

public class Field
{
    public string Label { get; set; }
    public string ExternalId { get; set; }
    public int FieldId { get; set; }
    public string Type { get; set; }
}

Is there a way to get all FieldIds from each Properties in FirstClass?

What i want is like this.

var fieldIds = // go through each fields (Field1 to FieldN) and select FieldId from each property.

Number of properties in FirstClass can be varied time to time. so i can't do it only depending on existing fields. I need to get value from all the fields

Akbar Badhusha
  • 2,415
  • 18
  • 30
  • 2
    possible of duplicate https://stackoverflow.com/questions/737151/how-to-get-the-list-of-properties-of-a-class – Antoine V Sep 04 '18 at 09:15
  • 1
    @ThierryV: not a duplicate, since he asks for a way to access the value of each property for an instance of FirstClass. But the question you linked is of course strongly related. – user82593 Sep 04 '18 at 09:25

3 Answers3

5

You have two options:

  1. "compile time"

    public class FirstClass
    {
        public Field Field1 { get; set; }
        public Field Field2 { get; set; }
        public Field Field3 { get; set; }
        public Field Field4 { get; set; }
        public Field Field5 { get; set; }
    
        public IEnumerable<Field> AllFields => 
               new [] { Field1, Field2, Field3, Field4, Field5 };
    }
    
  2. "run time" (using reflection)

    var firstClassInstance = new FirstClass();
    var allFields = firstClassInstance.GetType().GetProperties()
                      .Select(p => p.GetValue(firstClassInstance))
                      .OfType<Field>();
    
Vladi Pavelka
  • 916
  • 4
  • 12
  • Thanks. I will go with run time option. Because for some reasons i can't add AllFields option in the class :) @VladiPavelka – Akbar Badhusha Sep 04 '18 at 09:22
4

Try this if you want get each value of FieldId :

var FieldIds = new List<object>();
            var foo = new FirstClass();
            foo.Field1 = new Field() { FieldId = 1 };
            foo.Field2 = new Field() { FieldId = 2 };
            foo.Field3 = new Field() { FieldId = 3 };
            foo.Field4 = new Field() { FieldId = 4 };
            foo.Field5 = new Field() { FieldId = 5 };


            foreach (var prop in foo.GetType().GetProperties())
            {
                if(prop.PropertyType == typeof(Field))
                {
                    var field = prop.GetValue(foo, null) as Field;

                    FieldIds.Add(field.GetType().GetProperty("FieldId").GetValue(field,null));
                }
            }
Hossein
  • 3,083
  • 3
  • 16
  • 33
  • I would say projecting a value to a result directly feels better than creating an empty list beforehand to later repeatedly mutate it in a for-cycle - but that's my world – Vladi Pavelka Sep 04 '18 at 09:32
  • Thank you for your reply, i have updated the question. There can be more fields added to the same class, or existing fields can be removed. So i can't strictly follow your method. – Akbar Badhusha Sep 04 '18 at 09:33
1

Put them in an array.

var o = new FirstClass();
var fields = new Field[] { o.Field1, o.Field2, o.Field3, o.Field4, o.Field5 };

Then select over the array.

var fieldIds = fields.Select( f => f.FieldId );

P.S. You might consider exposing these fields as an array or List<Field> to begin with. Numbered properties is a code smell.

John Wu
  • 50,556
  • 8
  • 44
  • 80
  • Thanks for your reply. But i need to get this dynamically. The issue is there can be more fields added to the same class. – Akbar Badhusha Sep 04 '18 at 09:27
  • 1
    I'm curious. What maintainability issue are you solving? You have to add code to add a field; when you do that, update the array, it's that simple. It's probably the same file. I understand there is a risk that someone will add a new field and forget to update the array, but there is also the risk that someone will define a new property that returns a `Field` but was not intended to be in the list. Why not use a code pattern that forces the developer to make the list explicit? – John Wu Sep 04 '18 at 09:38