Как передать список объектов в качестве параметра в функцию, а затем использовать атрибуты объекта C # - PullRequest
1 голос
/ 15 октября 2019

Итак, это моя функция:

public bool CheckUniqueName<T>(string newName, List<T> list)
    {
        for (int i = 0; i < list.Count(); i++)
        {
            if (list[i].name == newName)
            {
                return false;
            }
        }
        return true;
    }

У меня есть этот список планет: private List<Planet> planetsList = new List<Planet>();

НО: я собираюсь использовать другие списки, такие как public List<Colony> ColonyList = new List<Colony>(); Вот почему мне нужноList<T>

И класс Planet:

class Planet
{
    ...
    public string name { get; }
    ... 
}

И я пытаюсь это: (some stuff) CheckUniqueName(name, planetsList) в другом классе

Как я понимаю, List<T> нене знаю об атрибуте .name.

Я пытался создать другой список и сделать что-то вроде этого:

public bool CheckUniqueName<T>(string newName, List<T> list)
    {
        if (list is List<Planet>)
        {
            var newList = planetsList;
        }
        for (int i = 0; i < list.Count(); i++)
        {
            if (list[i].name == newName)
            {
                return false;
            }
        }
        return true;
    }

Это не сработало, и то же самое с созданием нового списка не сделалтоже не работает.

Ответы [ 2 ]

6 голосов
/ 15 октября 2019

Здесь вы можете использовать общие ограничения:

public bool CheckUniqueName<T>(string newName, IEnumerable<T> items)
    where T : INamed

    => !items.Any(i => (i.Name == newName));

public interface INamed
{
    public Name { get; }
}

public class Planet : INamed
{
    public Name { get; }

    public Plant(string name)
    { 
        Name = name;
    }
}

public class Colony : INamed
{
    public Name { get; }

    public Colony(string name)
    { 
        Name = name;
    }
}
3 голосов
/ 15 октября 2019

Другой способ сделать это - передать делегата, который знает, как извлечь свойство name из любого типа, который вы передаете:

public bool CheckUniqueName<T>(IEnumerable<T> items, string newName, Func<T, string> nameSelector)
{
    foreach (var item in items)
    {
        string name = nameSelector(item);
        if (name == newName)
        {
            return false;
        }
    }

    return true;
}

Назовите его так:

CheckUniqueName(planetsList, "name", planet => planet.name);

Тогда ваше свойство name не нужно называть name - его можно называть как угодно.


Я написал длинную версию метода CheckUniqueName дляясности, но вы можете сократить его, используя linq:

public bool CheckUniqueName<T>(IEnumerable<T> items, string newName, Func<T, string> nameSelector)
{
    return !items.Any(item => newName == nameSelector(item));
}

Однако, если вы зайдете так далеко, вы можете также полностью отказаться от метода CheckUniqueName и вместо этого просто написать:

!plantsList.Any(x => x.name == "name");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...