-2

I have a class Person, that has some fields:

public class Person()
{
  private string _name;
  private bool _sex;
  private enum _race; 
}

Also I have some methods and constructors that generate values for these fields. They are not relevant really, so i omitted them.

For example, lets assume I need to instantiate this class 587 times. Manually I'd do it like this:

//pXXXX - is a name of each class, that would serve as an ID.
Person p0001 = new Person();
Person p0002 = new Person();

Person p0587 = new Person();

Obviously, it's a very inefficient way to do so. So I decided that I'd use some method to generate a list.

List<Person> listOfPeople = new List<Person>();

And have this method insert each out of 587 instances into this list. The problem is - I don't know how to generate all these instances automatically, giving them unique names.

Ilya_K
  • 1
  • 1
    Why would you need that many variables with unique names? Or do you need to generate unique value for the property ```_name```? – John Doe Aug 27 '21 at 10:56
  • If they are in an indexed list, you don't need unique names; refer to them as `listOfPeople[i]` – Mark Benningfield Aug 27 '21 at 10:58
  • As a general rule, if you find yourself writing variable names which contain indexes (like your `p...` variables with an index suffix), consider putting them in a container like an array or a list. If you index them with something that is not integer (e.g., a name) consider a dictionary. – Peter - Reinstate Monica Aug 27 '21 at 11:30

3 Answers3

3

If you mean unique variable name by the unique name, the following code is the cleanest way to achieve that.

List<Person> listOfPeople = new List<Person>();
for (int i = 0; i < 587; i++) 
{
    listOfPeople.Add(new Person());
}

Then you can call specific object by using the index number as such,

listOfPeople[0];

On the other hand, if you want to fill _name field with a unique data for every instance of object,

List<Person> listOfPeople = new List<Person>();
for (int i = 0; i < 587; i++) 
{
    var person = new Person()
    {
        _name = Guid.NewGuid().ToString()
    }
    listOfPeople.Add(person);
}
OhWelp
  • 167
  • 2
  • 10
  • Please add further details to expand on your answer, such as working code or documentation citations. – Community Aug 27 '21 at 11:08
  • @Mureinik thanks for the heads up, I hope the answer covers requirements now. – OhWelp Aug 27 '21 at 11:16
  • @OhWelp yes, now it seems to address that point. I'll remove my comment. – Mureinik Aug 27 '21 at 11:17
  • 1
    *Then you can call specific object by using the index number as such* - _name is private – Caius Jard Aug 27 '21 at 11:20
  • @CaiusJard Yes _name field should be made public or Person class should implement a public getter property for the private fields. On the other hand, it's not the related to the asked question but I still removed ._name part to avoid any confusion. – OhWelp Aug 27 '21 at 11:24
0

Having for example such enumerations:

public enum Gender
{
  Femele,
  Male,
  ...
}

public enum Ethnic
{
  African,
  Asian, 
  European,
  ...
}

And this class:

public class Person
{
  public string Name { get; set; }
  public Gender Gender { get; set; }
  public Ethnic Ethnic { get; set; }
}

You can use this loop:

using System.Linq;
using System.Collections.Generic;

int peopleCount = 587;

List<Person> people = new List<Person>();

foreach ( var index in Enumerable.Range(1, peopleCount) )
  people.Add(new Person());

Select can also be used as exposed by @lrpe.

The number can be set as a const or a static or an instance member that can be readonly or modifiable:

public const int PeopleCount = 587;

static public int PeopleCount { get; } = 587;

public int PeopleCount { get; set; } = 587;

The same for the object:

private readonly List<Person> People = new List<Person>();

Here it is a composite:

Understanding the Aggregation, Association, Composition

What is the difference between association, aggregation and composition?

Initializing members of a person depend on more details about your design and goal: you will probably set them via a user window or from a data file.

A default name can be assigned in the loop:

foreach ( var index in Enumerable.Range(1, PeopleCount) )
    People.Add(new Person { Name = $"Person {index}" });

Or using Select:

People.AddRange(Enumerable.Range(1, PeopleCount)
                          .Select(index => new Person { Name = $"Person {index}" }));

People = Enumerable.Range(1, PeopleCount)
                   .Select(index => new Person { Name = $"Person {index}" })
                   .ToList();

Perhaps you may prefer or want to use in addition to name an ID:

public class Person
{
  public Guid Id { get; } = Guid.NewGuid();
  public string Name { get; set; }
  public Gender Gender { get; set; }
  public Ethnic Ethnic { get; set; }
  public int Age { get; set; }
}

If setters are not needed set them private or init only, and also use real fields if needed like in your original code.

How do you like your primary keys?

How generate unique Integers based on GUIDs

Can using Ticks of DateTime.Now can generate duplicates unique identifiers?

Guid vs INT - Which is better as a primary key?

Universally unique identifier

0

Giving them unique names

You'll have to generate them. For example:

var listOfPeople = new List<Person>();

for (int i = 0; i < 587; i++) 
{
    listOfPeople.Add(new Person() {
      Name = "Sir " + Guid.NewGuid().ToString()
    });
}

Upgrade the private field in Person to be a public property

You can get as fancy as you like with the name generator, including using services/libraries that generate real sounding fake data

Don't get hung up on trying to generate variable names; they get lost during compilation anyway so a variable name is only meaningful to you as a developer and only when the program is being written. If there was a way to generate random variable names they wouldn't actually be that usable to you as a developer.

In general when you want to "programmatically generate a variable name" you use an array or list:

Person[] p = new Person[10]();

p[7] = new Person...

The p is the fixed part of the variable name. The index [7] is the changeable part. As a whole it refers to a single instance of a person, like Person p7 = new Person... would.. it's just that you can use eg an integer variable in place of the fixed 7 with an array, but you can't with one where the 7 is baked into the variable name from the get go..

Caius Jard
  • 72,509
  • 5
  • 49
  • 80