C # - MyClass.MyProperty [something]

I want to do something, but I don’t know how to describe it. I have this class

public class Company { private List<Person> _persons; private Person GetPersonByName(string name) { // My code to select Person is here, which is fine } } 

But I want to be able to do it.

 Company c; Person p = c.Persons["John"]; 

which must implicitly call GetPersonByName ("John").

Is it possible? What do I need to add to the company class?

Thanks in advance!

+6
source share
4 answers

Yes it is possible. You need to create an accessor class, for example:

 public class Company { private List<Person> _persons; public class PersonsIndexer { Company _owner; public PersonsIndexer(Company owner) { _owner = owner; } public Person this[string name] { get { return _owner._persons.FirstOrDefault(x=>x.Name == name); // or whatever code you have there } } } public PersonsIndexer Persons{ get; private set; } public Company() { Persons = new PersonsIndexer(this); } } 
+7
source

This is called an indexed property in C # .

+7
source

If you do this:

 public class Company { private List<Person> _persons; private Person GetPersonByName(string name) { // My code to select Person is here, which is fine } public Person this[string name] { get { return GetPersonByName(name); } } } 

then you can get a person:

 Company c; Person p = c["John"]; 

However, if you want c.Persons["John"] , then you must define a Person property that has a specific user type that has the specified indexed property. You can have a Persons property of type List, but then the List class does not have an indexed property that accepts a string. Why don't you just use the GetPerson(string name) method?

+2
source

FROM

 Persons["John"]; 

you use an indexer for any type on which the underlying object resides, in this case List. What you want is possible in two ways and maybe more, but these are my ideas at the moment:

The first approach: you can create a special collection list (say, PersonList: List) that overrides the indexer and passes an instance of Company in the constructor, so that you can request a client instance in the override implementation.

 public class PersonList: List<Person> { public new Person this[string name] { get { return company.GetMyPerson(name); } } } 

Second approach: you create an indexer on a company class directly and have something like c ["John"]

Now about these approaches β†’ The first one looks better from my point of view, because it violates the smaller design principles. It is not very pleasant to request a company using an indexer for people in the second approach ...

0
source

Source: https://habr.com/ru/post/890897/


All Articles