Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
kitsoRik
183 / 129 / 59
Регистрация: 30.10.2018
Сообщений: 534
1

Поиск по атрибуту класса

17.03.2019, 21:30. Просмотров 1564. Ответов 5
Метки нет (Все метки)

Привет всем, у меня есть объект в котором много полей, и я хочу создать универсальный метод в котором можно будет выбрать по каким критериям искать, к примеру есть класс объекта которого хочу искать:

C#
1
2
3
4
5
6
public class MyObj
{
public string name;
public int year;
public ColorType colorType;
}
И есть класс который хранит в себе список этих объектов:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class MyClass
{
public List<MyObj> myObjs;
 
public MyObj FindMyObj(string name)
{
foreach(MyObj my in myObjs)
if(MyObj.name == name)
return my;
return null;
}
 
public MyObj FindMyObj(ColorType colorType)
{
foreach(MyObj my in myObjs)
if(MyObj.colorType == colorType)
return my;
return null;
}
}
Берем к вниманию что ColorType это некий enum, не важно какой, важно то что я создал два метода, которые делают почти одно и то же, могу ли я как-то сделать один метод в котором укажу какой-то атрибут (перегрузки не подходят) и он будет искать, а еще лучше что бы я мог указать несколько атрибутов класса.

P.S. В моем понимании атрибуты это то же что и поля класса. И да, могу сделать конструкцию которая принимает все и по дефолту все это равно нулл и потом при поиске проверять не равны ли они нулл, но это уж слишком порнографично.

Вот о чем я говорил:

C#
1
2
3
4
5
6
7
public MyObj FindMyObj(string name == null, int year == -1, ColorType colorType == NullableColorType)
{
foreach(MyObj my in myObjs)
if((name == null || MyObj.name == name) && (year == -1 || MyObj.year == year) && (colorType == NullableColorType || MyObj.colorType == colorType))
return my;
return null;
}
И для поиска писать:
C#
1
MyObj m = FindMyObj(name: "Name1", colorType: colorType: ColorType.ColorGood);
P.S.S Писал все прям на форуме, могут быть ошибки.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.03.2019, 21:30
Ответы с готовыми решениями:

Поиск типа по его атрибуту
Есть класс: public class MessageBoard { public enum MessageType { ConnectedToServer,...

LINQ to XML - поиск по атрибуту
Здравствуйте хотелось бы попросить помощи в одном вопросе. Есть XML файл, записываю в него данные...

Поиск по числовому XML атрибуту
на msdn нашел пример поиск элемента по, атрибуту. XElement root =...

Поиск по атрибуту тега XML
Здравствуйте, нужна ваша помощь. У меня есть сохраненный XML документ с такими вот элементами ...

XML. Поиск узла по известному атрибуту
Хочу вывести определенный Caption в зависимости от ID, как это сделать? Хотя бы в двух словах....

5
КОП
600 / 438 / 139
Регистрация: 15.08.2010
Сообщений: 1,246
Завершенные тесты: 2
17.03.2019, 21:40 2
Лучший ответ Сообщение было отмечено kitsoRik как решение

Решение

Цитата Сообщение от kitsoRik Посмотреть сообщение
создать универсальный метод в котором можно будет выбрать по каким критериям искать
C#
1
2
3
4
5
6
7
8
9
10
11
        public static List<MyObj> myObjs = new List<MyObj>();
 
        public static MyObj FindMyObj(Predicate<MyObj> predicate)
        {
            return myObjs.FirstOrDefault(obj => predicate(obj));
        }
 
        public static unsafe void Main(string[] args)
        {
            MyObj m = FindMyObj(obj => obj.name == "Name1" && obj.colorType == ColorType.ColorGood);
        }
1
kitsoRik
183 / 129 / 59
Регистрация: 30.10.2018
Сообщений: 534
17.03.2019, 21:45  [ТС] 3
КОП, вызов я понял, но можно ли изменить метод FindMyObj, я просто не понимаю что он принимает в параметрах, и саму строчку
Цитата Сообщение от КОП Посмотреть сообщение
(obj => predicate(obj));
FirstOrDefault - это после первого компонента с соответвующими параметрами (если не найдет то дефолтный) но для меня это даже близко не понятно.

Не могли ли вы объяснить либо кинуть статью об этом?
0
КОП
600 / 438 / 139
Регистрация: 15.08.2010
Сообщений: 1,246
Завершенные тесты: 2
17.03.2019, 21:51 4
Цитата Сообщение от kitsoRik Посмотреть сообщение
но можно ли изменить метод FindMyObj
он по сути уже всё делает. про него можно забыть
Цитата Сообщение от kitsoRik Посмотреть сообщение
я просто не понимаю что он принимает в параметрах
предикат - такая функция, которая говорит подходит аргумент или нет
Цитата Сообщение от kitsoRik Посмотреть сообщение
но для меня это даже близко не понятно
не совсем понял что непонятно. под капотом там условный foreach как в вашем изначальном варианте. просто записано одним словом так сказать.
Цитата Сообщение от kitsoRik Посмотреть сообщение
Не могли ли вы объяснить либо кинуть статью об этом?
конкретных порекомендовать не могу. по сути любая статья по запросу "c# LINQ гайд"
и еще что такое лямбды в c#
1
kitsoRik
183 / 129 / 59
Регистрация: 30.10.2018
Сообщений: 534
17.03.2019, 22:05  [ТС] 5
Цитата Сообщение от КОП Посмотреть сообщение
не совсем понял что непонятно
Цитата Сообщение от КОП Посмотреть сообщение
obj => obj.name == "Name1" && obj.colorType == ColorType.ColorGood
именно это не понятно, а точнее что с ним дальше делаеться,
Цитата Сообщение от КОП Посмотреть сообщение
Predicate<MyObj> predicate
и как из этого достать мои параметры, мне кажеться если я перепишу вместо FindFirstOrDefault, свой код, то продвинусь сильно с этом плане.

Все что пока не понятно это как достаеться из Predicate мои значения.

Все другое более-менее знал до этого.

Добавлено через 7 минут
КОП, хотя, если я правильно понял, то это верно?
C#
1
2
3
4
5
foreach(MyObj my in myObjs)
            {
                if (predicate.Equals(my))
                    return my;
            }
0
КОП
600 / 438 / 139
Регистрация: 15.08.2010
Сообщений: 1,246
Завершенные тесты: 2
17.03.2019, 22:17 6
Лучший ответ Сообщение было отмечено kitsoRik как решение

Решение

Цитата Сообщение от kitsoRik Посмотреть сообщение
и как из этого достать мои параметры
это черный ящик, из него не надо ничего доставать.
Цитата Сообщение от kitsoRik Посмотреть сообщение
перепишу вместо FindFirstOrDefault, свой код, то продвинусь сильно с этом плане.
он у вас уже был. Вы не понимаете лямбды с предикатами судя по всему.

Вот 3 разных способа. Все они делают РОВНО ОДНО И ТО ЖЕ, просто написаны по-разному. третий способ к примеру для КАЖДОЙ комбинации требует отдельного метода

Алгоритм всё так же одинаковый:
решаем по каким полям искать
передаем это в метод FindMyObjects
в этом методе проходим по всем объектам и возвращаем подходящий

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
        public static MyObj FindMyObj1(Predicate<MyObj> predicate)
        {
            return myObjs.FirstOrDefault(obj => predicate(obj));
        }
 
        public static MyObj FindMyObj2(Func<MyObj, bool> predicate)
        {
            return myObjs.FirstOrDefault(predicate);
        }
 
        public static MyObj FindMyObj3(Predicate<MyObj> predicate)
        {
            foreach (MyObj my in myObjs)
            {
                if (predicate(my))
                    return my;
            }
 
            return null;
        }
 
        public static unsafe void Main(string[] args)
        {
            MyObj m1 = FindMyObj1(obj => obj.name == "Vasya" && obj.colorType == ColorType.ColorGood);
            MyObj m2 = FindMyObj2(obj => obj.name == "Vasya" && obj.colorType == ColorType.ColorGood);
            MyObj m3 = FindMyObj3(obj => obj.name == "Name1" && obj.colorType == ColorType.ColorGood);
 
            MyObj mm1 = FindMyObj1(TestByNameVasya);
            MyObj mm2 = FindMyObj2(TestByNameVasya);
            MyObj mm3 = FindMyObj3(TestByNameVasya);
        }
 
        public static bool TestByNameVasya(MyObj o)
        {
            return o.name == "Vasya";
        }
Добавлено через 1 минуту
Цитата Сообщение от kitsoRik Посмотреть сообщение
predicate.Equals(my)
этот предикат уже нужный метод, и вызывать его надо соответственно. например в коду выше это выглядело бы так
C#
1
2
predicate(my) //вызываем предикат
TestByNameVasya(my) //тоже вызываем предикат, который просто выглядит как обычный метод
0
17.03.2019, 22:17
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.03.2019, 22:17

XML Поиск элемента по атрибуту и запись в новый файл
Доброго времени суток. Пишу программу которая будет в xml искать элемент по значению атрибута и...

Доступ к закрытому атрибуту класса. Задача
Задача. Создать класс телевизор. У пользователя должна быть вводить номер канала, а также...

Доступ к атрибуту класса по его порядковому номеру
Имеется структура, нужно осуществить доступ к каждому её атрибуту по его порядковому номеру. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru