Co to jest predykat w c#? [duplikat]
To pytanie ma już odpowiedź tutaj:
- predykat Delegatów w C # 9 odpowiedzi
Jestem nowy w używaniu predykatów i właśnie nauczyłem się pisać:
Predicate<int> pre = delegate(int a){ a %2 == 0 };
Co zwróci predykat i jak jest przydatny podczas programowania?
4 answers
Predicate<T>
jest konstrukcją funkcjonalną zapewniającą wygodny sposób sprawdzenia, czy coś jest prawdą o danym obiekcie T
.
Na przykład załóżmy, że mam klasę:
class Person {
public string Name { get; set; }
public int Age { get; set; }
}
Powiedzmy, że mam kogoś o imieniu Oscar.
bez za pomocą Predicate<Person>
(lub Linq, lub cokolwiek z tych fantazyjnych rzeczy), zawsze mogłem to osiągnąć, wykonując następujące czynności:
Person oscar = null;
foreach (Person person in people) {
if (person.Name == "Oscar") {
oscar = person;
break;
}
}
if (oscar != null) {
// Oscar exists!
}
To jest w porządku, ale powiedzmy, że chcę sprawdź, czy istnieje osoba o imieniu "Ruth"? Albo osoba, która ma 17 lat?
Używając Predicate<Person>
, mogę znaleźć te rzeczy używając dużo mniej kodu:
Predicate<Person> oscarFinder = (Person p) => { return p.Name == "Oscar"; };
Predicate<Person> ruthFinder = (Person p) => { return p.Name == "Ruth"; };
Predicate<Person> seventeenYearOldFinder = (Person p) => { return p.Age == 17; };
Person oscar = people.Find(oscarFinder);
Person ruth = people.Find(ruthFinder);
Person seventeenYearOld = people.Find(seventeenYearOldFinder);
Zauważ, że powiedziałem dużo mniej kodu , nie dużo szybciej . Częstym błędnym przekonaniem programistów jest to, że jeśli coś zajmuje jedną linię, musi działać lepiej niż coś, co zajmuje dziesięć linii. Ale za kulisami metoda Find
, która zajmuje Predicate<T>
, jest po prostu wyliczaniem. To samo dotyczy wielu Funkcjonalność Linq.
Predicate<int> pre = delegate(int a){ return a % 2 == 0; };
Tutaj mamy Predicate<int> pre
, który pobiera int a
i zwraca a % 2 == 0
. Jest to zasadniczo test dla liczby parzystej. Oznacza to:
pre(1) == false;
pre(2) == true;
I tak dalej. Oznacza to również, że jeśli masz List<int> ints
i chcesz znaleźć pierwszą liczbę parzystą, możesz to zrobić:
int firstEven = ints.Find(pre);
Oczywiście, jak w przypadku każdego innego typu, którego można użyć w kodzie, dobrym pomysłem jest podanie swojego zmienne nazwy opisowe; radzę więc zmienić powyższe pre
na coś w rodzaju evenFinder
lub isEven
-- coś w tym stylu. Następnie powyższy kod jest o wiele jaśniejszy:
int firstEven = ints.Find(evenFinder);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-10 19:24:04
Predykat zawsze zwróci wartość logiczną z definicji.
Predicate<T>
jest w zasadzie identyczna z Func<T,bool>
.
Predykaty są bardzo przydatne w programowaniu. Są one często używane, aby umożliwić dostarczenie logiki w czasie wykonywania, które mogą być tak proste lub tak skomplikowane, jak to konieczne.
Na przykład WPF używa Predicate<T>
jako wejścia do filtrowania widoku ICollectionView listy. Pozwala to na pisanie logiki, która może zwracać wartość logiczną określającą, czy dany element powinien być zawarte w ostatecznym widoku. Logika może być bardzo prosta (wystarczy zwrócić wartość logiczną obiektu) lub bardzo złożona, wszystko zależy od Ciebie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-10 18:54:00
Poniższy kod może pomóc ci zrozumieć rzeczywiste użycie predykatów (w połączeniu z nazwanymi iteratorami).
namespace Predicate
{
class Person
{
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
foreach (Person person in OlderThan(18))
{
Console.WriteLine(person.Age);
}
}
static IEnumerable<Person> OlderThan(int age)
{
Predicate<Person> isOld = x => x.Age > age;
Person[] persons = { new Person { Age = 10 }, new Person { Age = 20 }, new Person { Age = 19 } };
foreach (Person person in persons)
if (isOld(person)) yield return person;
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-03 11:51:56
W C# predykaty są po prostu delegatami zwracającymi wartości logiczne. Są przydatne (z mojego doświadczenia), gdy przeszukujesz kolekcję przedmiotów i chcesz czegoś konkretnego.
Ostatnio natknąłem się na nie w użyciu kontrolek stron trzecich (takich jak treeviews), więc kiedy muszę znaleźć węzeł w drzewie, używam .Metoda Find() i podaj predykat, który zwróci konkretny węzeł, którego szukam. W twoim przykładzie, jeśli 'a' mod 2 jest równe 0, delegat zwróci true. Przyznane, gdy Szukam węzła w widoku drzewa, porównuję jego nazwę, tekst i właściwości wartości dla dopasowania. Kiedy delegat znajdzie dopasowanie, zwraca konkretny węzeł, którego szukałem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-10 19:00:07