0

I want to user a foreach loop to add to a c# list without using the list properties Key name.

I have a list such as

public class Bus 
{
    public string Val1 { get; set; }
    public string Val2 { get; set; }
    public string Val3 { get; set; }
    public string Val4 { get; set; }
    public string Val5 { get; set; }
    public string Val6 { get; set; }

    // ...

    public string Val127 { get; set; }
}

The lists I want to populate can have over 200 properties so I am trying to find a quick way to populate them without writing out the properties. I want to populate this from a one dimensional array (line) using something like this

j = 0
for (int i = 0; i < lines.Length; i++)
{
    foreach(Bus BusProp in BusList)
    {
        BusProp[j] = line[i+j];
        j =+ 1;
    }
}

This is not working. Any suggestions are appreciated

Franz Wimmer
  • 1,477
  • 3
  • 20
  • 38
user1781272
  • 862
  • 2
  • 14
  • 25
  • 2
    Then put your 127 string properties in an array – Steve Sep 12 '16 at 12:23
  • Possible duplicate of [How to get the list of properties of a class?](http://stackoverflow.com/questions/737151/how-to-get-the-list-of-properties-of-a-class) – Sinatr Sep 12 '16 at 12:23
  • 1
    Sounds like a quite bad design. One class with 200 properties? Devide your class into smaller ones following the Single-Responsibility-Priciple. – MakePeaceGreatAgain Sep 12 '16 at 12:24
  • 3
    127 properties?? smells bad design,/code. I would suggest look for `Dictionary` or similar data structure. – Hari Prasad Sep 12 '16 at 12:24
  • Very possibly bad coding. The tables I am working with can have over 250 columns. it's an old db structure that i am forced to work with. – user1781272 Sep 12 '16 at 12:26

4 Answers4

1

Why not use

public class Bus
{
    public string[] Val = new string[127];
}

j = 0;
for (int i = 0; i<lines.Length; i++)
{
    foreach(Bus BusProp in BusList)
    {
        BusProp.Val[j] = line[i + j];
        j =+ 1;
    }
}
Franz Wimmer
  • 1,477
  • 3
  • 20
  • 38
Pepernoot
  • 3,409
  • 3
  • 21
  • 46
1

If you can't change the class definition, your main alternative option is to use reflection.

void Main()
{
  var bus = new Bus();
  var data = new string[6] { "A", "B", "C", "D", "E", "F" };

  for (var i = 1; i <= 6; i++)
  {
    bus.GetType().GetProperty("Val" + i.ToString()).SetValue(bus, data[i - 1]);
  }

  Console.WriteLine(bus.Val5); // E
}

public class Bus 
{
  public string Val1 {get;set;}
  public string Val2 {get;set;}
  public string Val3 {get;set;}
  public string Val4 {get;set;}
  public string Val5 {get;set;}
  public string Val6 {get;set;}
}

Needless to say, this is quite expensive, and may be hard to maintain. Make sure you don't have a more reasonable option (e.g. changing the class to contain arrays instead of indexed properties, using code generation...) before using this.

Even if your database has some COBOL-like monstrosity with 150 indexed columns, there shouldn't be a reason why your application can't deal with them in the form of Item[34] instead of Item34 - isolate the application code from the fixed constraints you're not happy with.

Luaan
  • 62,244
  • 7
  • 97
  • 116
0

Try this

var typ = typeof(Bus);

var prop = typ.GetProperty($"Val{j}");

Pepernoot
  • 3,409
  • 3
  • 21
  • 46
0

I feel like the answers so far haven't satisfied your needs, thus here's my solution:

    static void Main(string[] args)
    {
        //Create a string array containing the desired property names, in this case I'll use a loop
        List<string> DesiredProperties = new List<string>(); 

        for (int i = 0; i < 100; i++)
        {
            DesiredProperties.Add(string.Format("Property{0}", i));
        }

        //Call the method that returns the object and pass the array as parameter
        var Bus = CreateDynamicObject(DesiredProperties);

        //Display one of the properties
        Console.WriteLine(Bus.Property99);
        Console.Read();
    }
    private static dynamic CreateDynamicObject(List<string> PropertyList)
    {
        dynamic obj = new System.Dynamic.ExpandoObject();
        foreach (string Prop in PropertyList)
        {
            //You can add the properties using a dictionary. You can also give them an initial value
            var dict = (IDictionary<string, object>)obj;
            dict.Add(Prop, string.Format("The value of {0}", Prop));
        }
        return obj;
    }

This piece of code will add 100 properties to var "Bus", which can be accessed and applied a value at will.

Innat3
  • 3,561
  • 2
  • 11
  • 29