A couple of things:
1.) As for your actual question, you have two options:
You can iterate over the Bar
field (or property, if you change it to a property as outlined below) in your code:
Foo foo = new Foo();
foreach(Bar bar in foo.Bar)
{
...
}
Or you can make Foo
implement IEnumerable<Bar>
(this is more complicated):
public class Foo : IEnumerable<Bar>
{
.. your existing code goes here
public IEnumerator<Bar> GetEnumerator()
{
return Bar.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Bar.GetEnumerator();
}
}
This will allow you to do this:
Foo foo = new Foo();
foreach(Bar bar in foo)
{
}
Personally, I would recommend the first option. It's simpler, and unless Foo
really is (rather than it just has) a collection of Bar
objects, then it seems more intuitive.
2.) What you have above are not properties, they're public fields. A property has a getter and a setter, and looks something like this:
public class Foo
{
public string Something
{
get { return ...; }
set { ... = value; }
}
}
Properties usually operate on a single variable, called a backing store. For the above property, something like this:
public class Foo
{
private string something;
public string Something
{
get
{
return something;
}
set
{
something = value;
}
}
}
Strictly speaking, you could put absolutely any block of code that returns a string in the get
block, and you can put anything at all in the set
block (including nothing, though that's not a good idea).
Properties allow you to define something that behaves like a field (since you can assign it using the equals sign) but uses the behavior you specify when its value is retrieved or set. However, one of the issues with very simple properties (that just directly get/set a backing variable without any other logic) is that it's a little verbose for what it actually does. That's why C# 3.0 introduced the concept of auto properties, which look like this:
public class Foo
{
public string Something { get; set; }
}
Here, Something
looks a bit like a field, but it's actually a property. The C# compiler recognizes this syntax (replacing the code blocks for both get
and set
with just a semicolon) and creates a backing variable for you and inserts the code to read from it and write to it.