tags:

views:

32

answers:

2

I have a class that has an internal list of other objects like so:

public class Parent
{
    List<Child> _children;
}

where Child say looks like this:

public class Child
{
    public string Name;
}

What I want to do is set up parent where the members of _children can be accessed like so:

...
Child kid = parentInstance["Billy"]; // would find a Child instance 
                                     // whose name value is Billy
...

Is this possible? I could obviously do something like this:

Child kid = parentInstance.GetChild("Billy");

But I prefer the array/dictionary like syntax. This isn't a big deal if it isn't, and I don't want to have to jump through a million hoops for what amounts to syntactic sugar.

+5  A: 

You could define an indexed property to the Parent class:

public class Parent
{
    List<Child> _children;

    public Child this[string name] 
    {
        get
        {
            return (_children ?? Enumerable.Empty<Child>())
                .Where(c => c.Name == name)
                .FirstOrDefault();
        }
    }
}
Darin Dimitrov
Damn my slow typing skills :(
SirDemon
Dammit. However long they make you wait before accepting an answer now is still too long... :)
Tim Coker
Should note that if you have two children with the same name you are SOL in accessing the second one.
Scott Chamberlain
Yeah, for this particular code, I enforce that each name be unique. :) would be impossible to access second member without that.
Tim Coker
A: 

The "array syntax" is not best suited for what you need, and it's rather obsolete too :)

Nowadays in .net we have Linq and the lambda extension methods, that make our life when working with collections really easy.

You can do:

IEnumerable<Child> childs = parentInstance.Childrens.Where(child => child.Name == "Billy"); //this will get all childs named billy

Child child = parentInstance.Childrens.FirstOrDefault(child => child.Name == "Billy"); //this will get the first child named billy only, or null if no billy is found

You can also write the above queries in linq syntax instead of lambda. For instance, the first query will be like this:

IEnumerable<Child> childs = from child in parentInstance.Childrens where child.Name == "billy" select child;
Matteo Mosca
Yeah, I'm familiar with linq, love it, and use the piss out of it. For what you propose to work, though, I'd have to expose the _children list, which I want to avoid. (Notice that _children is private in the original code.)
Tim Coker
The question was not about the best method suited to find an item in a list. He specifically asked about "array syntax" or indexers.
SirDemon
I know he requested "array syntax" but I think that suggesting a possible better way of doing things isn't a crime.
Matteo Mosca
@Tim, you can expose the children as an IEnumerable property, which allows all the LINQy goodness without compromising encapsulation. I prefer this over an indexer syntax, generally, as parent["Billy"] is not as natural of an idiom to me (is Billy the child, the grandparent, the uncle?)
Dan Bryant