Reputation: 995
I have class MyModel and some object of MyModel.
I need for-loop or foreach properties of object without reflection. How implemented?
Class example:
public class MyModel
{
public string Level1_TypeName { get; set; }
public string Level1_AttrType { get; set; }
public string Level1_AttrValue { get; set; }
public string Level2_TypeName { get; set; }
public string Level2_AttrType { get; set; }
public string Level2_AttrValue { get; set; }
public string Level3_TypeName { get; set; }
public string Level3_AttrType { get; set; }
public string Level3_AttrValue { get; set; }
public string Level4_TypeName { get; set; }
public string Level4_AttrType { get; set; }
public string Level4_AttrValue { get; set; }
public string Level5_TypeName { get; set; }
public string Level5_AttrType { get; set; }
public string Level5_AttrValue { get; set; }
public string Level6_TypeName { get; set; }
}
Upvotes: 1
Views: 3607
Reputation: 1
Below code does not use reflections
using System.ComponentModel;
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(instance);
foreach (PropertyDescriptor prop in props)
{
}
Upvotes: 0
Reputation: 62472
If you're looking to avoid reflection then you're going to have to write code by hand. You could add an method that returns an enumerator:
IEnumerable<Tuple<int,string,string,string>> GetLevels()
{
yield return Tuple.Create(1, Level1_TypeName, Level1_AttrType, Level1_AttrValue);
yield return Tuple.Create(2, Level2_TypeName, Level2_AttrType, Level2_AttrValue);
yield return Tuple.Create(3, Level3_TypeName, Level3_AttrType, Level3_AttrValue);
yield return Tuple.Create(4, Level4_TypeName, Level4_AttrType, Level4_AttrValue);
yield return Tuple.Create(5, Level5_TypeName, Level5_AttrType, Level5_AttrValue);
yield return Tuple.Create(6, Level6_TypeName, Level6_AttrType, Level6_AttrValue);
}
Now you can say:
foreach(var i in myModel.GetLevels())
{
Console.WriteLine("{0},{1},{2},{3}",i.Item1,i.Item2,i.Item3,i.Item4);
}
Upvotes: 1
Reputation: 12766
You can use reflection to make a dictionary with all your values:
var obj = new MyModel();
var dictionary = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToDictionary(p => p.Name, p => p.GetGetMethod().Invoke(obj, null));
foreach (var kv in dictionary)
Console.WriteLine(kv.Key + ": " + kv.Value ?? "null");
But I do recommend you read and use the answer of Jon Skeet
If you don't want to use reflection you can't loop through an objects properties.
You can use a bit of reflection in your model to implement an ienumerable:
public class MyModel : IEnumerable<KeyValuePair<string, object>>
{
public string Level1_TypeName { get; set; }
public string Level1_AttrType { get; set; }
public string Level1_AttrValue { get; set; }
public string Level2_TypeName { get; set; }
public string Level2_AttrType { get; set; }
public string Level2_AttrValue { get; set; }
public string Level3_TypeName { get; set; }
public string Level3_AttrType { get; set; }
public string Level3_AttrValue { get; set; }
public string Level4_TypeName { get; set; }
public string Level4_AttrType { get; set; }
public string Level4_AttrValue { get; set; }
public string Level5_TypeName { get; set; }
public string Level5_AttrType { get; set; }
public string Level5_AttrValue { get; set; }
public string Level6_TypeName { get; set; }
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
return this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToDictionary(p => p.Name, p => p.GetGetMethod().Invoke(this, null)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
You can then use your class like this:
var obj = new MyModel();
foreach(var kv in obj)
Console.WriteLine(kv.Key + ": " + kv.Value ?? "null");
Upvotes: 3
Reputation: 1499780
I would strongly suggest that you take two actions:
TypeName
, AttrType
, AttrValue
At that point, it will be really easy to iterate over the properties without using reflection... and your code will be much clearer, too.
Upvotes: 11