1

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; }  
}
3
  • 3
    Use reflection to achieve that, but I bet it's not what you really want to do. Elaborate on your goals in the question. Commented Dec 11, 2013 at 14:49
  • 4
    I don't understand why so many people want to do this without using Reflection. It's like saying "I want to cut a piece of wood but I don't want to use a saw, how do I do that?" The right tool for the job is the right tool for the job. Commented Dec 11, 2013 at 14:51
  • @DavidStratton: In this case I believe the right tool for the job is a redesign, rather than reflection. Commented Dec 12, 2013 at 6:45

4 Answers 4

11

I would strongly suggest that you take two actions:

  • Create a new type to encapsulate the combination of TypeName, AttrType, AttrValue
  • Change your model to contain a collection of that class rather than several separate properties.

At that point, it will be really easy to iterate over the properties without using reflection... and your code will be much clearer, too.

Sign up to request clarification or add additional context in comments.

Comments

3

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");

5 Comments

Thank you, SynerCoder. I would prefer Jon Skeet answer
@zrabzdn: I'm confused as to why you've accepted this one then - especially as it uses reflection, which you explicitly said you didn't want to do...
@Jon Skeet: I'm accepted redesign and not used reflection. Implement my job using your advice and get a good decision
@zrabzdn: Right - so again, why have you accepted this answer (the green tick) which does use reflection?
@Jon Skeet: It's my mistake I don't want't to accepted reflection. But now I can't return accepted
1

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);
}

Comments

0

Below code does not use reflections

using System.ComponentModel;

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(instance);
foreach (PropertyDescriptor prop in props)
{   
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.